| 1 | /* $Id: subdivider.cpp,v 1.1 2000-02-09 08:50:29 jeroen Exp $ */
|
|---|
| 2 | /*
|
|---|
| 3 | ** License Applicability. Except to the extent portions of this file are
|
|---|
| 4 | ** made subject to an alternative license as permitted in the SGI Free
|
|---|
| 5 | ** Software License B, Version 1.0 (the "License"), the contents of this
|
|---|
| 6 | ** file are subject only to the provisions of the License. You may not use
|
|---|
| 7 | ** this file except in compliance with the License. You may obtain a copy
|
|---|
| 8 | ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
|
|---|
| 9 | ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
|
|---|
| 10 | **
|
|---|
| 11 | ** http://oss.sgi.com/projects/FreeB
|
|---|
| 12 | **
|
|---|
| 13 | ** Note that, as provided in the License, the Software is distributed on an
|
|---|
| 14 | ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
|
|---|
| 15 | ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
|
|---|
| 16 | ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
|
|---|
| 17 | ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
|
|---|
| 18 | **
|
|---|
| 19 | ** Original Code. The Original Code is: OpenGL Sample Implementation,
|
|---|
| 20 | ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
|
|---|
| 21 | ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
|
|---|
| 22 | ** Copyright in any portions created by third parties is as indicated
|
|---|
| 23 | ** elsewhere herein. All Rights Reserved.
|
|---|
| 24 | **
|
|---|
| 25 | ** Additional Notice Provisions: The application programming interfaces
|
|---|
| 26 | ** established by SGI in conjunction with the Original Code are The
|
|---|
| 27 | ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
|
|---|
| 28 | ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
|
|---|
| 29 | ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
|
|---|
| 30 | ** Window System(R) (Version 1.3), released October 19, 1998. This software
|
|---|
| 31 | ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
|
|---|
| 32 | ** published by SGI, but has not been independently verified as being
|
|---|
| 33 | ** compliant with the OpenGL(R) version 1.2.1 Specification.
|
|---|
| 34 | */
|
|---|
| 35 |
|
|---|
| 36 | /*
|
|---|
| 37 | * subdivider.cxx
|
|---|
| 38 | *
|
|---|
| 39 | * $Date: 2000-02-09 08:50:29 $ $Revision: 1.1 $
|
|---|
| 40 | * $Header: /home/ktk/tmp/odin/2007/netlabs.cvs/odin32/src/opengl/glu/nurbs/internals/subdivider.cpp,v 1.1 2000-02-09 08:50:29 jeroen Exp $
|
|---|
| 41 | */
|
|---|
| 42 |
|
|---|
| 43 | #include <stdlib.h>
|
|---|
| 44 | #include "glimports.h"
|
|---|
| 45 | #include "myassert.h"
|
|---|
| 46 | #include "mystdio.h"
|
|---|
| 47 | #include "subdivider.h"
|
|---|
| 48 | #include "arc.h"
|
|---|
| 49 | #include "bezierarc.h"
|
|---|
| 50 | #include "bin.h"
|
|---|
| 51 | #include "renderhints.h"
|
|---|
| 52 | #include "backend.h"
|
|---|
| 53 | #include "mapdesc.h"
|
|---|
| 54 | #include "quilt.h"
|
|---|
| 55 | #include "patchlist.h"
|
|---|
| 56 | #include "patch.h"
|
|---|
| 57 | #include "nurbsconsts.h"
|
|---|
| 58 | #include "trimvertpool.h"
|
|---|
| 59 | #include "simplemath.h"
|
|---|
| 60 |
|
|---|
| 61 | #include "polyUtil.h" //for function area()
|
|---|
| 62 |
|
|---|
| 63 | //#define PARTITION_TEST
|
|---|
| 64 | #ifdef PARTITION_TEST
|
|---|
| 65 | #include "partitionY.h"
|
|---|
| 66 | #include "monoTriangulation.h"
|
|---|
| 67 | #include "dataTransform.h"
|
|---|
| 68 | #include "monoChain.h"
|
|---|
| 69 |
|
|---|
| 70 | #endif
|
|---|
| 71 |
|
|---|
| 72 |
|
|---|
| 73 | #define OPTIMIZE_UNTRIMED_CASE
|
|---|
| 74 |
|
|---|
| 75 |
|
|---|
| 76 | Bin*
|
|---|
| 77 | Subdivider::makePatchBoundary( const REAL *from, const REAL *to )
|
|---|
| 78 | {
|
|---|
| 79 | Bin* ret = new Bin();
|
|---|
| 80 | REAL smin = from[0];
|
|---|
| 81 | REAL smax = to[0];
|
|---|
| 82 | REAL tmin = from[1];
|
|---|
| 83 | REAL tmax = to[1];
|
|---|
| 84 |
|
|---|
| 85 | pjarc = 0;
|
|---|
| 86 |
|
|---|
| 87 | Arc_ptr jarc = new(arcpool) Arc( arc_bottom, 0 );
|
|---|
| 88 | arctessellator.bezier( jarc, smin, smax, tmin, tmin );
|
|---|
| 89 | ret->addarc( jarc );
|
|---|
| 90 | pjarc = jarc->append( pjarc );
|
|---|
| 91 |
|
|---|
| 92 | jarc = new(arcpool) Arc( arc_right, 0 );
|
|---|
| 93 | arctessellator.bezier( jarc, smax, smax, tmin, tmax );
|
|---|
| 94 | ret->addarc( jarc );
|
|---|
| 95 | pjarc = jarc->append( pjarc );
|
|---|
| 96 |
|
|---|
| 97 | jarc = new(arcpool) Arc( arc_top, 0 );
|
|---|
| 98 | arctessellator.bezier( jarc, smax, smin, tmax, tmax );
|
|---|
| 99 | ret->addarc( jarc );
|
|---|
| 100 | pjarc = jarc->append( pjarc );
|
|---|
| 101 |
|
|---|
| 102 | jarc = new(arcpool) Arc( arc_left, 0 );
|
|---|
| 103 | arctessellator.bezier( jarc, smin, smin, tmax, tmin );
|
|---|
| 104 | ret->addarc( jarc );
|
|---|
| 105 | jarc->append( pjarc );
|
|---|
| 106 |
|
|---|
| 107 | assert( jarc->check() != 0 );
|
|---|
| 108 | return ret;
|
|---|
| 109 | }
|
|---|
| 110 |
|
|---|
| 111 | /*---------------------------------------------------------------------------
|
|---|
| 112 | * Subdivider - construct a subdivider
|
|---|
| 113 | *---------------------------------------------------------------------------
|
|---|
| 114 | */
|
|---|
| 115 |
|
|---|
| 116 | Subdivider::Subdivider( Renderhints& r, Backend& b )
|
|---|
| 117 | : arcpool( sizeof( Arc), 1, "arcpool" ),
|
|---|
| 118 | bezierarcpool( sizeof( BezierArc ), 1, "Bezarcpool" ),
|
|---|
| 119 | pwlarcpool( sizeof( PwlArc ), 1, "Pwlarcpool" ),
|
|---|
| 120 | renderhints( r ),
|
|---|
| 121 | arctessellator( trimvertexpool, pwlarcpool ),
|
|---|
| 122 | backend( b ),
|
|---|
| 123 | slicer( b )
|
|---|
| 124 | {
|
|---|
| 125 | }
|
|---|
| 126 |
|
|---|
| 127 | void
|
|---|
| 128 | Subdivider::setJumpbuffer( JumpBuffer *j )
|
|---|
| 129 | {
|
|---|
| 130 | jumpbuffer = j;
|
|---|
| 131 | }
|
|---|
| 132 |
|
|---|
| 133 | /*---------------------------------------------------------------------------
|
|---|
| 134 | * clear - reset all state after possible error condition
|
|---|
| 135 | *---------------------------------------------------------------------------
|
|---|
| 136 | */
|
|---|
| 137 |
|
|---|
| 138 | void
|
|---|
| 139 | Subdivider::clear( void )
|
|---|
| 140 | {
|
|---|
| 141 | trimvertexpool.clear();
|
|---|
| 142 | arcpool.clear();
|
|---|
| 143 | pwlarcpool.clear();
|
|---|
| 144 | bezierarcpool.clear();
|
|---|
| 145 | }
|
|---|
| 146 |
|
|---|
| 147 | /*---------------------------------------------------------------------------
|
|---|
| 148 | * ~Subdivider - destroy a subdivider
|
|---|
| 149 | *---------------------------------------------------------------------------
|
|---|
| 150 | */
|
|---|
| 151 |
|
|---|
| 152 | Subdivider::~Subdivider( void )
|
|---|
| 153 | {
|
|---|
| 154 | }
|
|---|
| 155 |
|
|---|
| 156 | /*---------------------------------------------------------------------------
|
|---|
| 157 | * addArc - add a bezier arc to a trim loop and to a bin
|
|---|
| 158 | *---------------------------------------------------------------------------
|
|---|
| 159 | */
|
|---|
| 160 | void
|
|---|
| 161 | Subdivider::addArc( REAL *cpts, Quilt *quilt, long _nuid )
|
|---|
| 162 | {
|
|---|
| 163 | BezierArc *bezierArc = new(bezierarcpool) BezierArc;
|
|---|
| 164 | Arc *jarc = new(arcpool) Arc( arc_none, _nuid );
|
|---|
| 165 | jarc->pwlArc = 0;
|
|---|
| 166 | jarc->bezierArc = bezierArc;
|
|---|
| 167 | bezierArc->order = quilt->qspec->order;
|
|---|
| 168 | bezierArc->stride = quilt->qspec->stride;
|
|---|
| 169 | bezierArc->mapdesc = quilt->mapdesc;
|
|---|
| 170 | bezierArc->cpts = cpts;
|
|---|
| 171 | initialbin.addarc( jarc );
|
|---|
| 172 | pjarc = jarc->append( pjarc );
|
|---|
| 173 | }
|
|---|
| 174 |
|
|---|
| 175 | /*---------------------------------------------------------------------------
|
|---|
| 176 | * addArc - add a pwl arc to a trim loop and to a bin
|
|---|
| 177 | *---------------------------------------------------------------------------
|
|---|
| 178 | */
|
|---|
| 179 |
|
|---|
| 180 | void
|
|---|
| 181 | Subdivider::addArc( int npts, TrimVertex *pts, long _nuid )
|
|---|
| 182 | {
|
|---|
| 183 | Arc *jarc = new(arcpool) Arc( arc_none, _nuid );
|
|---|
| 184 | jarc->pwlArc = new(pwlarcpool) PwlArc( npts, pts );
|
|---|
| 185 | initialbin.addarc( jarc );
|
|---|
| 186 | pjarc = jarc->append( pjarc );
|
|---|
| 187 | }
|
|---|
| 188 |
|
|---|
| 189 | void
|
|---|
| 190 | Subdivider::beginQuilts( void )
|
|---|
| 191 | {
|
|---|
| 192 | qlist = 0;
|
|---|
| 193 | }
|
|---|
| 194 |
|
|---|
| 195 | void
|
|---|
| 196 | Subdivider::addQuilt( Quilt *quilt )
|
|---|
| 197 | {
|
|---|
| 198 | quilt->next = qlist;
|
|---|
| 199 | qlist = quilt;
|
|---|
| 200 | }
|
|---|
| 201 |
|
|---|
| 202 | /*---------------------------------------------------------------------------
|
|---|
| 203 | * drawSurfaces - main entry point for surface tessellation
|
|---|
| 204 | *---------------------------------------------------------------------------
|
|---|
| 205 | */
|
|---|
| 206 |
|
|---|
| 207 | void
|
|---|
| 208 | Subdivider::drawSurfaces( long nuid )
|
|---|
| 209 | {
|
|---|
| 210 | renderhints.init( );
|
|---|
| 211 |
|
|---|
| 212 | if (qlist == NULL)
|
|---|
| 213 | {
|
|---|
| 214 | //initialbin could be nonempty due to some errors
|
|---|
| 215 | freejarcs(initialbin);
|
|---|
| 216 | return;
|
|---|
| 217 | }
|
|---|
| 218 |
|
|---|
| 219 | for( Quilt *q = qlist; q; q = q->next ) {
|
|---|
| 220 | if( q->isCulled( ) == CULL_TRIVIAL_REJECT ) {
|
|---|
| 221 | freejarcs( initialbin );
|
|---|
| 222 | return;
|
|---|
| 223 | }
|
|---|
| 224 | }
|
|---|
| 225 |
|
|---|
| 226 |
|
|---|
| 227 | REAL from[2], to[2];
|
|---|
| 228 | qlist->getRange( from, to, spbrkpts, tpbrkpts );
|
|---|
| 229 | #ifdef OPTIMIZE_UNTRIMED_CASE
|
|---|
| 230 | //perform optimization only when the samplng method is
|
|---|
| 231 | //DOMAIN_DISTANCE and the display methdo is either
|
|---|
| 232 | //fill or outline_polygon.
|
|---|
| 233 | int optimize = (is_domain_distance_sampling && (renderhints.display_method != N_OUTLINE_PATCH));
|
|---|
| 234 | #endif
|
|---|
| 235 |
|
|---|
| 236 | if( ! initialbin.isnonempty() ) {
|
|---|
| 237 | #ifdef OPTIMIZE_UNTRIMED_CASE
|
|---|
| 238 | if(! optimize )
|
|---|
| 239 | {
|
|---|
| 240 |
|
|---|
| 241 | makeBorderTrim( from, to );
|
|---|
| 242 | }
|
|---|
| 243 | #else
|
|---|
| 244 | makeBorderTrim( from, to );
|
|---|
| 245 | #endif
|
|---|
| 246 | } else {
|
|---|
| 247 | REAL rate[2];
|
|---|
| 248 | qlist->findRates( spbrkpts, tpbrkpts, rate );
|
|---|
| 249 |
|
|---|
| 250 | if( decompose( initialbin, min(rate[0], rate[1]) ) )
|
|---|
| 251 | mylongjmp( jumpbuffer, 31 );
|
|---|
| 252 | }
|
|---|
| 253 |
|
|---|
| 254 | backend.bgnsurf( renderhints.wiretris, renderhints.wirequads, nuid );
|
|---|
| 255 |
|
|---|
| 256 | #ifdef PARTITION_TEST
|
|---|
| 257 | if( initialbin.isnonempty() && spbrkpts.end-2 == spbrkpts.start &&
|
|---|
| 258 | tpbrkpts.end-2 == tpbrkpts.start)
|
|---|
| 259 | {
|
|---|
| 260 | for(int i=spbrkpts.start; i<spbrkpts.end-1; i++){
|
|---|
| 261 | for(int j=tpbrkpts.start; j<tpbrkpts.end-1; j++){
|
|---|
| 262 | Real pta[2], ptb[2];
|
|---|
| 263 | pta[0] = spbrkpts.pts[i];
|
|---|
| 264 | ptb[0] = spbrkpts.pts[i+1];
|
|---|
| 265 | pta[1] = tpbrkpts.pts[j];
|
|---|
| 266 | ptb[1] = tpbrkpts.pts[j+1];
|
|---|
| 267 | qlist->downloadAll(pta, ptb, backend);
|
|---|
| 268 |
|
|---|
| 269 | directedLine *poly;
|
|---|
| 270 |
|
|---|
| 271 | {
|
|---|
| 272 |
|
|---|
| 273 | poly = bin_to_DLineLoops(initialbin);
|
|---|
| 274 |
|
|---|
| 275 | poly=poly->deleteDegenerateLinesAllPolygons();
|
|---|
| 276 |
|
|---|
| 277 | sampledLine* retSampledLines;
|
|---|
| 278 | //printf("before MC_partition\n");
|
|---|
| 279 | poly = MC_partitionY(poly, &retSampledLines);
|
|---|
| 280 | //printf("after MC_partition\n");
|
|---|
| 281 |
|
|---|
| 282 | }
|
|---|
| 283 |
|
|---|
| 284 |
|
|---|
| 285 | {
|
|---|
| 286 | primStream pStream(5000,5000);
|
|---|
| 287 | directedLine* temp;
|
|---|
| 288 |
|
|---|
| 289 | for(temp=poly; temp != NULL; temp=temp->getNextPolygon())
|
|---|
| 290 |
|
|---|
| 291 | monoTriangulation(temp, &pStream);
|
|---|
| 292 |
|
|---|
| 293 | slicer.evalStream(&pStream);
|
|---|
| 294 |
|
|---|
| 295 | }
|
|---|
| 296 | //need to clean up space
|
|---|
| 297 | }
|
|---|
| 298 | }
|
|---|
| 299 | freejarcs( initialbin );
|
|---|
| 300 | backend.endsurf();
|
|---|
| 301 | return;
|
|---|
| 302 |
|
|---|
| 303 | /*
|
|---|
| 304 | printf("num_polygons=%i\n", poly->numPolygons());
|
|---|
| 305 | printf("num_edges=%i\n", poly->numEdgesAllPolygons());
|
|---|
| 306 | poly->writeAllPolygons("zloutputFile");
|
|---|
| 307 | return;
|
|---|
| 308 | {
|
|---|
| 309 | primStream pStream(20,20);
|
|---|
| 310 | for(directedLine* tempD = poly; tempD != NULL; tempD = tempD->getNextPolygon())
|
|---|
| 311 | monoTriangulation(tempD, &pStream);
|
|---|
| 312 | }
|
|---|
| 313 | return;
|
|---|
| 314 | */
|
|---|
| 315 | }
|
|---|
| 316 | #endif //PARTITION_TEST
|
|---|
| 317 |
|
|---|
| 318 |
|
|---|
| 319 | #ifdef OPTIMIZE_UNTRIMED_CASE
|
|---|
| 320 | if( (!initialbin.isnonempty()) && optimize )
|
|---|
| 321 | {
|
|---|
| 322 | int i,j;
|
|---|
| 323 | int num_u_steps;
|
|---|
| 324 | int num_v_steps;
|
|---|
| 325 | for(i=spbrkpts.start; i<spbrkpts.end-1; i++){
|
|---|
| 326 | for(j=tpbrkpts.start; j<tpbrkpts.end-1; j++){
|
|---|
| 327 | Real pta[2], ptb[2];
|
|---|
| 328 | pta[0] = spbrkpts.pts[i];
|
|---|
| 329 | ptb[0] = spbrkpts.pts[i+1];
|
|---|
| 330 | pta[1] = tpbrkpts.pts[j];
|
|---|
| 331 | ptb[1] = tpbrkpts.pts[j+1];
|
|---|
| 332 | qlist->downloadAll(pta, ptb, backend);
|
|---|
| 333 |
|
|---|
| 334 | num_u_steps = (int) (domain_distance_u_rate * (ptb[0]-pta[0]));
|
|---|
| 335 | num_v_steps = (int) (domain_distance_v_rate * (ptb[1]-pta[1]));
|
|---|
| 336 |
|
|---|
| 337 | if(num_u_steps <= 0) num_u_steps = 1;
|
|---|
| 338 | if(num_v_steps <= 0) num_v_steps = 1;
|
|---|
| 339 |
|
|---|
| 340 | backend.surfgrid(pta[0], ptb[0], num_u_steps,
|
|---|
| 341 | ptb[1], pta[1], num_v_steps);
|
|---|
| 342 | backend.surfmesh(0,0,num_u_steps,num_v_steps);
|
|---|
| 343 |
|
|---|
| 344 |
|
|---|
| 345 |
|
|---|
| 346 | continue;
|
|---|
| 347 | /* the following is left for reference purpose, don't delete
|
|---|
| 348 | {
|
|---|
| 349 | Bin* tempSource;
|
|---|
| 350 | Patchlist patchlist(qlist, pta, ptb);
|
|---|
| 351 | patchlist.getstepsize();
|
|---|
| 352 |
|
|---|
| 353 | tempSource=makePatchBoundary(pta, ptb);
|
|---|
| 354 |
|
|---|
| 355 | tessellation(*tempSource, patchlist);
|
|---|
| 356 |
|
|---|
| 357 | render(*tempSource);
|
|---|
| 358 | delete tempSource;
|
|---|
| 359 | }
|
|---|
| 360 | */
|
|---|
| 361 | }
|
|---|
| 362 | }
|
|---|
| 363 | }
|
|---|
| 364 | else
|
|---|
| 365 | subdivideInS( initialbin );
|
|---|
| 366 | #else
|
|---|
| 367 |
|
|---|
| 368 | subdivideInS( initialbin );
|
|---|
| 369 | #endif
|
|---|
| 370 |
|
|---|
| 371 | backend.endsurf();
|
|---|
| 372 |
|
|---|
| 373 | }
|
|---|
| 374 |
|
|---|
| 375 | void
|
|---|
| 376 | Subdivider::subdivideInS( Bin& source )
|
|---|
| 377 | {
|
|---|
| 378 | if( renderhints.display_method == N_OUTLINE_PARAM ) {
|
|---|
| 379 | outline( source );
|
|---|
| 380 | freejarcs( source );
|
|---|
| 381 | } else {
|
|---|
| 382 | setArcTypeBezier();
|
|---|
| 383 | setNonDegenerate();
|
|---|
| 384 | splitInS( source, spbrkpts.start, spbrkpts.end );
|
|---|
| 385 | }
|
|---|
| 386 | }
|
|---|
| 387 |
|
|---|
| 388 |
|
|---|
| 389 | /*---------------------------------------------------------------------------
|
|---|
| 390 | * splitInS - split a patch and a bin by an isoparametric line
|
|---|
| 391 | *---------------------------------------------------------------------------
|
|---|
| 392 | */
|
|---|
| 393 |
|
|---|
| 394 | void
|
|---|
| 395 | Subdivider::splitInS( Bin& source, int start, int end )
|
|---|
| 396 | {
|
|---|
| 397 | if( source.isnonempty() ) {
|
|---|
| 398 | if( start != end ) {
|
|---|
| 399 | int i = start + (end - start) / 2;
|
|---|
| 400 | Bin left, right;
|
|---|
| 401 | split( source, left, right, 0, spbrkpts.pts[i] );
|
|---|
| 402 | splitInS( left, start, i );
|
|---|
| 403 | splitInS( right, i+1, end );
|
|---|
| 404 | } else {
|
|---|
| 405 | if( start == spbrkpts.start || start == spbrkpts.end ) {
|
|---|
| 406 | freejarcs( source );
|
|---|
| 407 | } else if( renderhints.display_method == N_OUTLINE_PARAM_S ) {
|
|---|
| 408 | outline( source );
|
|---|
| 409 | freejarcs( source );
|
|---|
| 410 | } else {
|
|---|
| 411 | setArcTypeBezier();
|
|---|
| 412 | setNonDegenerate();
|
|---|
| 413 | s_index = start;
|
|---|
| 414 | splitInT( source, tpbrkpts.start, tpbrkpts.end );
|
|---|
| 415 | }
|
|---|
| 416 | }
|
|---|
| 417 | }
|
|---|
| 418 | }
|
|---|
| 419 |
|
|---|
| 420 | /*---------------------------------------------------------------------------
|
|---|
| 421 | * splitInT - split a patch and a bin by an isoparametric line
|
|---|
| 422 | *---------------------------------------------------------------------------
|
|---|
| 423 | */
|
|---|
| 424 |
|
|---|
| 425 | void
|
|---|
| 426 | Subdivider::splitInT( Bin& source, int start, int end )
|
|---|
| 427 | {
|
|---|
| 428 | if( source.isnonempty() ) {
|
|---|
| 429 | if( start != end ) {
|
|---|
| 430 | int i = start + (end - start) / 2;
|
|---|
| 431 | Bin left, right;
|
|---|
| 432 | split( source, left, right, 1, tpbrkpts.pts[i] );
|
|---|
| 433 | splitInT( left, start, i );
|
|---|
| 434 | splitInT( right, i+1, end );
|
|---|
| 435 | } else {
|
|---|
| 436 | if( start == tpbrkpts.start || start == tpbrkpts.end ) {
|
|---|
| 437 | freejarcs( source );
|
|---|
| 438 | } else if( renderhints.display_method == N_OUTLINE_PARAM_ST ) {
|
|---|
| 439 | outline( source );
|
|---|
| 440 | freejarcs( source );
|
|---|
| 441 | } else {
|
|---|
| 442 | t_index = start;
|
|---|
| 443 | setArcTypeBezier();
|
|---|
| 444 | setDegenerate();
|
|---|
| 445 |
|
|---|
| 446 | REAL pta[2], ptb[2];
|
|---|
| 447 | pta[0] = spbrkpts.pts[s_index-1];
|
|---|
| 448 | pta[1] = tpbrkpts.pts[t_index-1];
|
|---|
| 449 |
|
|---|
| 450 | ptb[0] = spbrkpts.pts[s_index];
|
|---|
| 451 | ptb[1] = tpbrkpts.pts[t_index];
|
|---|
| 452 | qlist->downloadAll( pta, ptb, backend );
|
|---|
| 453 |
|
|---|
| 454 | Patchlist patchlist( qlist, pta, ptb );
|
|---|
| 455 | /*
|
|---|
| 456 | printf("-------samplingSplit-----\n");
|
|---|
| 457 | source.show("samplingSplit source");
|
|---|
| 458 | */
|
|---|
| 459 | samplingSplit( source, patchlist, renderhints.maxsubdivisions, 0 );
|
|---|
| 460 | setNonDegenerate();
|
|---|
| 461 | setArcTypeBezier();
|
|---|
| 462 | }
|
|---|
| 463 | }
|
|---|
| 464 | }
|
|---|
| 465 | }
|
|---|
| 466 |
|
|---|
| 467 | /*--------------------------------------------------------------------------
|
|---|
| 468 | * samplingSplit - recursively subdivide patch, cull check each subpatch
|
|---|
| 469 | *--------------------------------------------------------------------------
|
|---|
| 470 | */
|
|---|
| 471 |
|
|---|
| 472 | void
|
|---|
| 473 | Subdivider::samplingSplit(
|
|---|
| 474 | Bin& source,
|
|---|
| 475 | Patchlist& patchlist,
|
|---|
| 476 | int subdivisions,
|
|---|
| 477 | int param )
|
|---|
| 478 | {
|
|---|
| 479 | if( ! source.isnonempty() ) return;
|
|---|
| 480 |
|
|---|
| 481 | if( patchlist.cullCheck() == CULL_TRIVIAL_REJECT ) {
|
|---|
| 482 | freejarcs( source );
|
|---|
| 483 | return;
|
|---|
| 484 | }
|
|---|
| 485 |
|
|---|
| 486 | patchlist.getstepsize();
|
|---|
| 487 |
|
|---|
| 488 | if( renderhints.display_method == N_OUTLINE_PATCH ) {
|
|---|
| 489 | tessellation( source, patchlist );
|
|---|
| 490 | outline( source );
|
|---|
| 491 | freejarcs( source );
|
|---|
| 492 | return;
|
|---|
| 493 | }
|
|---|
| 494 |
|
|---|
| 495 | //patchlist.clamp();
|
|---|
| 496 |
|
|---|
| 497 | tessellation( source, patchlist );
|
|---|
| 498 |
|
|---|
| 499 | if( patchlist.needsSamplingSubdivision() && (subdivisions > 0) ) {
|
|---|
| 500 | if( ! patchlist.needsSubdivision( 0 ) )
|
|---|
| 501 | param = 1;
|
|---|
| 502 | else if( ! patchlist.needsSubdivision( 1 ) )
|
|---|
| 503 | param = 0;
|
|---|
| 504 | else
|
|---|
| 505 | param = 1 - param;
|
|---|
| 506 |
|
|---|
| 507 | Bin left, right;
|
|---|
| 508 | REAL mid = ( patchlist.pspec[param].range[0] +
|
|---|
| 509 | patchlist.pspec[param].range[1] ) * 0.5;
|
|---|
| 510 | split( source, left, right, param, mid );
|
|---|
| 511 | Patchlist subpatchlist( patchlist, param, mid );
|
|---|
| 512 | samplingSplit( left, subpatchlist, subdivisions-1, param );
|
|---|
| 513 | samplingSplit( right, patchlist, subdivisions-1, param );
|
|---|
| 514 | } else {
|
|---|
| 515 | setArcTypePwl();
|
|---|
| 516 | setDegenerate();
|
|---|
| 517 | nonSamplingSplit( source, patchlist, subdivisions, param );
|
|---|
| 518 | setDegenerate();
|
|---|
| 519 | setArcTypeBezier();
|
|---|
| 520 | }
|
|---|
| 521 | }
|
|---|
| 522 |
|
|---|
| 523 | void
|
|---|
| 524 | Subdivider::nonSamplingSplit(
|
|---|
| 525 | Bin& source,
|
|---|
| 526 | Patchlist& patchlist,
|
|---|
| 527 | int subdivisions,
|
|---|
| 528 | int param )
|
|---|
| 529 | {
|
|---|
| 530 | if( patchlist.needsNonSamplingSubdivision() && (subdivisions > 0) ) {
|
|---|
| 531 | param = 1 - param;
|
|---|
| 532 |
|
|---|
| 533 | Bin left, right;
|
|---|
| 534 | REAL mid = ( patchlist.pspec[param].range[0] +
|
|---|
| 535 | patchlist.pspec[param].range[1] ) * 0.5;
|
|---|
| 536 | split( source, left, right, param, mid );
|
|---|
| 537 | Patchlist subpatchlist( patchlist, param, mid );
|
|---|
| 538 | if( left.isnonempty() )
|
|---|
| 539 | if( subpatchlist.cullCheck() == CULL_TRIVIAL_REJECT )
|
|---|
| 540 | freejarcs( left );
|
|---|
| 541 | else
|
|---|
| 542 | nonSamplingSplit( left, subpatchlist, subdivisions-1, param );
|
|---|
| 543 | if( right.isnonempty() )
|
|---|
| 544 | if( patchlist.cullCheck() == CULL_TRIVIAL_REJECT )
|
|---|
| 545 | freejarcs( right );
|
|---|
| 546 | else
|
|---|
| 547 | nonSamplingSplit( right, patchlist, subdivisions-1, param );
|
|---|
| 548 |
|
|---|
| 549 | } else {
|
|---|
| 550 | // make bbox calls
|
|---|
| 551 | patchlist.bbox();
|
|---|
| 552 | backend.patch( patchlist.pspec[0].range[0], patchlist.pspec[0].range[1],
|
|---|
| 553 | patchlist.pspec[1].range[0], patchlist.pspec[1].range[1] );
|
|---|
| 554 |
|
|---|
| 555 | if( renderhints.display_method == N_OUTLINE_SUBDIV ) {
|
|---|
| 556 | outline( source );
|
|---|
| 557 | freejarcs( source );
|
|---|
| 558 | } else {
|
|---|
| 559 | setArcTypePwl();
|
|---|
| 560 | setDegenerate();
|
|---|
| 561 | findIrregularS( source );
|
|---|
| 562 | monosplitInS( source, smbrkpts.start, smbrkpts.end );
|
|---|
| 563 | }
|
|---|
| 564 | }
|
|---|
| 565 | }
|
|---|
| 566 |
|
|---|
| 567 | /*--------------------------------------------------------------------------
|
|---|
| 568 | * tessellation - set tessellation of interior and boundary of patch
|
|---|
| 569 | *--------------------------------------------------------------------------
|
|---|
| 570 | */
|
|---|
| 571 |
|
|---|
| 572 | void
|
|---|
| 573 | Subdivider::tessellation( Bin& bin, Patchlist &patchlist )
|
|---|
| 574 | {
|
|---|
| 575 | // tessellate unsampled trim curves
|
|---|
| 576 | tessellate( bin, patchlist.pspec[1].sidestep[1], patchlist.pspec[0].sidestep[1],
|
|---|
| 577 | patchlist.pspec[1].sidestep[0], patchlist.pspec[0].sidestep[0] );
|
|---|
| 578 |
|
|---|
| 579 | // set interior sampling rates
|
|---|
| 580 | slicer.setstriptessellation( patchlist.pspec[0].stepsize, patchlist.pspec[1].stepsize );
|
|---|
| 581 |
|
|---|
| 582 | //added by zl: set the order which will be used in slicer.c++
|
|---|
| 583 | slicer.set_ulinear( (patchlist.get_uorder() == 2));
|
|---|
| 584 | slicer.set_vlinear( (patchlist.get_vorder() == 2));
|
|---|
| 585 |
|
|---|
| 586 | // set boundary sampling rates
|
|---|
| 587 | stepsizes[0] = patchlist.pspec[1].stepsize;
|
|---|
| 588 | stepsizes[1] = patchlist.pspec[0].stepsize;
|
|---|
| 589 | stepsizes[2] = patchlist.pspec[1].stepsize;
|
|---|
| 590 | stepsizes[3] = patchlist.pspec[0].stepsize;
|
|---|
| 591 | }
|
|---|
| 592 |
|
|---|
| 593 | /*---------------------------------------------------------------------------
|
|---|
| 594 | * monosplitInS - split a patch and a bin by an isoparametric line
|
|---|
| 595 | *---------------------------------------------------------------------------
|
|---|
| 596 | */
|
|---|
| 597 |
|
|---|
| 598 | void
|
|---|
| 599 | Subdivider::monosplitInS( Bin& source, int start, int end )
|
|---|
| 600 | {
|
|---|
| 601 | if( source.isnonempty() ) {
|
|---|
| 602 | if( start != end ) {
|
|---|
| 603 | int i = start + (end - start) / 2;
|
|---|
| 604 | Bin left, right;
|
|---|
| 605 | split( source, left, right, 0, smbrkpts.pts[i] );
|
|---|
| 606 | monosplitInS( left, start, i );
|
|---|
| 607 | monosplitInS( right, i+1, end );
|
|---|
| 608 | } else {
|
|---|
| 609 | if( renderhints.display_method == N_OUTLINE_SUBDIV_S ) {
|
|---|
| 610 | outline( source );
|
|---|
| 611 | freejarcs( source );
|
|---|
| 612 | } else {
|
|---|
| 613 | setArcTypePwl();
|
|---|
| 614 | setDegenerate();
|
|---|
| 615 | findIrregularT( source );
|
|---|
| 616 | monosplitInT( source, tmbrkpts.start, tmbrkpts.end );
|
|---|
| 617 | }
|
|---|
| 618 | }
|
|---|
| 619 | }
|
|---|
| 620 | }
|
|---|
| 621 |
|
|---|
| 622 | /*---------------------------------------------------------------------------
|
|---|
| 623 | * monosplitInT - split a patch and a bin by an isoparametric line
|
|---|
| 624 | *---------------------------------------------------------------------------
|
|---|
| 625 | */
|
|---|
| 626 |
|
|---|
| 627 | void
|
|---|
| 628 | Subdivider::monosplitInT( Bin& source, int start, int end )
|
|---|
| 629 | {
|
|---|
| 630 | if( source.isnonempty() ) {
|
|---|
| 631 | if( start != end ) {
|
|---|
| 632 | int i = start + (end - start) / 2;
|
|---|
| 633 | Bin left, right;
|
|---|
| 634 | split( source, left, right, 1, tmbrkpts.pts[i] );
|
|---|
| 635 | monosplitInT( left, start, i );
|
|---|
| 636 | monosplitInT( right, i+1, end );
|
|---|
| 637 | } else {
|
|---|
| 638 | if( renderhints.display_method == N_OUTLINE_SUBDIV_ST ) {
|
|---|
| 639 | outline( source );
|
|---|
| 640 | freejarcs( source );
|
|---|
| 641 | } else {
|
|---|
| 642 | /*
|
|---|
| 643 | printf("*******render\n");
|
|---|
| 644 | source.show("source\n");
|
|---|
| 645 | */
|
|---|
| 646 | render( source );
|
|---|
| 647 | freejarcs( source );
|
|---|
| 648 | }
|
|---|
| 649 | }
|
|---|
| 650 | }
|
|---|
| 651 | }
|
|---|
| 652 |
|
|---|
| 653 |
|
|---|
| 654 | /*----------------------------------------------------------------------------
|
|---|
| 655 | * findIrregularS - determine points of non-monotonicity is s direction
|
|---|
| 656 | *----------------------------------------------------------------------------
|
|---|
| 657 | */
|
|---|
| 658 |
|
|---|
| 659 | void
|
|---|
| 660 | Subdivider::findIrregularS( Bin& bin )
|
|---|
| 661 | {
|
|---|
| 662 | assert( bin.firstarc()->check() != 0 );
|
|---|
| 663 |
|
|---|
| 664 | smbrkpts.grow( bin.numarcs() );
|
|---|
| 665 |
|
|---|
| 666 | for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) {
|
|---|
| 667 | REAL *a = jarc->prev->tail();
|
|---|
| 668 | REAL *b = jarc->tail();
|
|---|
| 669 | REAL *c = jarc->head();
|
|---|
| 670 |
|
|---|
| 671 | if( b[1] == a[1] && b[1] == c[1] ) continue;
|
|---|
| 672 |
|
|---|
| 673 | //corrected code
|
|---|
| 674 | if((b[1]<=a[1] && b[1] <= c[1]) ||
|
|---|
| 675 | (b[1]>=a[1] && b[1] >= c[1]))
|
|---|
| 676 | {
|
|---|
| 677 | //each arc (jarc, jarc->prev, jarc->next) is a
|
|---|
| 678 | //monotone arc consisting of multiple line segements.
|
|---|
| 679 | //it may happen that jarc->prev and jarc->next are the same,
|
|---|
| 680 | //that is, jarc->prev and jarc form a closed loop.
|
|---|
| 681 | //In such case, a and c will be the same.
|
|---|
| 682 | if(a[0]==c[0] && a[1] == c[1])
|
|---|
| 683 | {
|
|---|
| 684 | if(jarc->pwlArc->npts >2)
|
|---|
| 685 | {
|
|---|
| 686 | c = jarc->pwlArc->pts[jarc->pwlArc->npts-2].param;
|
|---|
| 687 | }
|
|---|
| 688 | else
|
|---|
| 689 | {
|
|---|
| 690 | assert(jarc->prev->pwlArc->npts>2);
|
|---|
| 691 | a = jarc->prev->pwlArc->pts[jarc->prev->pwlArc->npts-2].param;
|
|---|
| 692 | }
|
|---|
| 693 |
|
|---|
| 694 | }
|
|---|
| 695 | if(area(a,b,c) < 0)
|
|---|
| 696 | {
|
|---|
| 697 | smbrkpts.add(b[0]);
|
|---|
| 698 | }
|
|---|
| 699 |
|
|---|
| 700 | }
|
|---|
| 701 |
|
|---|
| 702 | /* old code,
|
|---|
| 703 | if( b[1] <= a[1] && b[1] <= c[1] ) {
|
|---|
| 704 | if( ! ccwTurn_tr( jarc->prev, jarc ) )
|
|---|
| 705 | smbrkpts.add( b[0] );
|
|---|
| 706 | } else if( b[1] >= a[1] && b[1] >= c[1] ) {
|
|---|
| 707 | if( ! ccwTurn_tl( jarc->prev, jarc ) )
|
|---|
| 708 | smbrkpts.add( b[0] );
|
|---|
| 709 | }
|
|---|
| 710 | */
|
|---|
| 711 |
|
|---|
| 712 | }
|
|---|
| 713 |
|
|---|
| 714 | smbrkpts.filter();
|
|---|
| 715 | }
|
|---|
| 716 |
|
|---|
| 717 | /*----------------------------------------------------------------------------
|
|---|
| 718 | * findIrregularT - determine points of non-monotonicity in t direction
|
|---|
| 719 | * where one arc is parallel to the s axis.
|
|---|
| 720 | *----------------------------------------------------------------------------
|
|---|
| 721 | */
|
|---|
| 722 |
|
|---|
| 723 | void
|
|---|
| 724 | Subdivider::findIrregularT( Bin& bin )
|
|---|
| 725 | {
|
|---|
| 726 | assert( bin.firstarc()->check() != 0 );
|
|---|
| 727 |
|
|---|
| 728 | tmbrkpts.grow( bin.numarcs() );
|
|---|
| 729 |
|
|---|
| 730 | for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) {
|
|---|
| 731 | REAL *a = jarc->prev->tail();
|
|---|
| 732 | REAL *b = jarc->tail();
|
|---|
| 733 | REAL *c = jarc->head();
|
|---|
| 734 |
|
|---|
| 735 | if( b[0] == a[0] && b[0] == c[0] ) continue;
|
|---|
| 736 |
|
|---|
| 737 | if( b[0] <= a[0] && b[0] <= c[0] ) {
|
|---|
| 738 | if( a[1] != b[1] && b[1] != c[1] ) continue;
|
|---|
| 739 | if( ! ccwTurn_sr( jarc->prev, jarc ) )
|
|---|
| 740 | tmbrkpts.add( b[1] );
|
|---|
| 741 | } else if ( b[0] >= a[0] && b[0] >= c[0] ) {
|
|---|
| 742 | if( a[1] != b[1] && b[1] != c[1] ) continue;
|
|---|
| 743 | if( ! ccwTurn_sl( jarc->prev, jarc ) )
|
|---|
| 744 | tmbrkpts.add( b[1] );
|
|---|
| 745 | }
|
|---|
| 746 | }
|
|---|
| 747 | tmbrkpts.filter( );
|
|---|
| 748 | }
|
|---|
| 749 |
|
|---|
| 750 | /*-----------------------------------------------------------------------------
|
|---|
| 751 | * makeBorderTrim - if no user input trimming data then create
|
|---|
| 752 | * a trimming curve around the boundaries of the Quilt. The curve consists of
|
|---|
| 753 | * four Jordan arcs, one for each side of the Quilt, connected, of course,
|
|---|
| 754 | * head to tail.
|
|---|
| 755 | *-----------------------------------------------------------------------------
|
|---|
| 756 | */
|
|---|
| 757 |
|
|---|
| 758 | void
|
|---|
| 759 | Subdivider::makeBorderTrim( const REAL *from, const REAL *to )
|
|---|
| 760 | {
|
|---|
| 761 | REAL smin = from[0];
|
|---|
| 762 | REAL smax = to[0];
|
|---|
| 763 | REAL tmin = from[1];
|
|---|
| 764 | REAL tmax = to[1];
|
|---|
| 765 |
|
|---|
| 766 | pjarc = 0;
|
|---|
| 767 |
|
|---|
| 768 | Arc_ptr jarc = new(arcpool) Arc( arc_bottom, 0 );
|
|---|
| 769 | arctessellator.bezier( jarc, smin, smax, tmin, tmin );
|
|---|
| 770 | initialbin.addarc( jarc );
|
|---|
| 771 | pjarc = jarc->append( pjarc );
|
|---|
| 772 |
|
|---|
| 773 | jarc = new(arcpool) Arc( arc_right, 0 );
|
|---|
| 774 | arctessellator.bezier( jarc, smax, smax, tmin, tmax );
|
|---|
| 775 | initialbin.addarc( jarc );
|
|---|
| 776 | pjarc = jarc->append( pjarc );
|
|---|
| 777 |
|
|---|
| 778 | jarc = new(arcpool) Arc( arc_top, 0 );
|
|---|
| 779 | arctessellator.bezier( jarc, smax, smin, tmax, tmax );
|
|---|
| 780 | initialbin.addarc( jarc );
|
|---|
| 781 | pjarc = jarc->append( pjarc );
|
|---|
| 782 |
|
|---|
| 783 | jarc = new(arcpool) Arc( arc_left, 0 );
|
|---|
| 784 | arctessellator.bezier( jarc, smin, smin, tmax, tmin );
|
|---|
| 785 | initialbin.addarc( jarc );
|
|---|
| 786 | jarc->append( pjarc );
|
|---|
| 787 |
|
|---|
| 788 | assert( jarc->check() != 0 );
|
|---|
| 789 | }
|
|---|
| 790 |
|
|---|
| 791 | /*----------------------------------------------------------------------------
|
|---|
| 792 | * render - renders all monotone regions in a bin and frees the bin
|
|---|
| 793 | *----------------------------------------------------------------------------
|
|---|
| 794 | */
|
|---|
| 795 |
|
|---|
| 796 | void
|
|---|
| 797 | Subdivider::render( Bin& bin )
|
|---|
| 798 | {
|
|---|
| 799 | bin.markall();
|
|---|
| 800 |
|
|---|
| 801 | #ifdef N_ISOLINE_S
|
|---|
| 802 | slicer.setisolines( ( renderhints.display_method == N_ISOLINE_S ) ? 1 : 0 );
|
|---|
| 803 | #else
|
|---|
| 804 | slicer.setisolines( 0 );
|
|---|
| 805 | #endif
|
|---|
| 806 |
|
|---|
| 807 | for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) {
|
|---|
| 808 | if( jarc->ismarked() ) {
|
|---|
| 809 | assert( jarc->check( ) != 0 );
|
|---|
| 810 | Arc_ptr jarchead = jarc;
|
|---|
| 811 | do {
|
|---|
| 812 | jarc->clearmark();
|
|---|
| 813 | jarc = jarc->next;
|
|---|
| 814 | } while (jarc != jarchead);
|
|---|
| 815 | slicer.slice( jarc );
|
|---|
| 816 | }
|
|---|
| 817 | }
|
|---|
| 818 | }
|
|---|
| 819 |
|
|---|
| 820 | /*---------------------------------------------------------------------------
|
|---|
| 821 | * outline - render the trimmed patch by outlining the boundary
|
|---|
| 822 | *---------------------------------------------------------------------------
|
|---|
| 823 | */
|
|---|
| 824 |
|
|---|
| 825 | void
|
|---|
| 826 | Subdivider::outline( Bin& bin )
|
|---|
| 827 | {
|
|---|
| 828 | bin.markall();
|
|---|
| 829 | for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) {
|
|---|
| 830 | if( jarc->ismarked() ) {
|
|---|
| 831 | assert( jarc->check( ) != 0 );
|
|---|
| 832 | Arc_ptr jarchead = jarc;
|
|---|
| 833 | do {
|
|---|
| 834 | slicer.outline( jarc );
|
|---|
| 835 | jarc->clearmark();
|
|---|
| 836 | jarc = jarc->prev;
|
|---|
| 837 | } while (jarc != jarchead);
|
|---|
| 838 | }
|
|---|
| 839 | }
|
|---|
| 840 | }
|
|---|
| 841 |
|
|---|
| 842 | /*---------------------------------------------------------------------------
|
|---|
| 843 | * freejarcs - free all arcs in a bin
|
|---|
| 844 | *---------------------------------------------------------------------------
|
|---|
| 845 | */
|
|---|
| 846 |
|
|---|
| 847 | void
|
|---|
| 848 | Subdivider::freejarcs( Bin& bin )
|
|---|
| 849 | {
|
|---|
| 850 | bin.adopt(); /* XXX - should not be necessary */
|
|---|
| 851 |
|
|---|
| 852 | Arc_ptr jarc;
|
|---|
| 853 | while( jarc = bin.removearc() ) {
|
|---|
| 854 | if( jarc->pwlArc ) jarc->pwlArc->deleteMe( pwlarcpool ); jarc->pwlArc = 0;
|
|---|
| 855 | if( jarc->bezierArc) jarc->bezierArc->deleteMe( bezierarcpool ); jarc->bezierArc = 0;
|
|---|
| 856 | jarc->deleteMe( arcpool );
|
|---|
| 857 | }
|
|---|
| 858 | }
|
|---|
| 859 |
|
|---|
| 860 | /*----------------------------------------------------------------------------
|
|---|
| 861 | * tessellate - tessellate all Bezier arcs in a bin
|
|---|
| 862 | * 1) only accepts linear Bezier arcs as input
|
|---|
| 863 | * 2) the Bezier arcs are stored in the pwlArc structure
|
|---|
| 864 | * 3) only vertical or horizontal lines work
|
|---|
| 865 | * -- should
|
|---|
| 866 | * 1) represent Bezier arcs in BezierArc structure
|
|---|
| 867 | * (this requires a multitude of changes to the code)
|
|---|
| 868 | * 2) accept high degree Bezier arcs (hard)
|
|---|
| 869 | * 3) map the curve onto the surface to determine tessellation
|
|---|
| 870 | * 4) work for curves of arbitrary geometry
|
|---|
| 871 | *----------------------------------------------------------------------------
|
|---|
| 872 | */
|
|---|
| 873 |
|
|---|
| 874 |
|
|---|
| 875 | void
|
|---|
| 876 | Subdivider::tessellate( Bin& bin, REAL rrate, REAL trate, REAL lrate, REAL brate )
|
|---|
| 877 | {
|
|---|
| 878 | for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) {
|
|---|
| 879 | if( jarc->isbezier( ) ) {
|
|---|
| 880 | assert( jarc->pwlArc->npts == 2 );
|
|---|
| 881 | TrimVertex *pts = jarc->pwlArc->pts;
|
|---|
| 882 | REAL s1 = pts[0].param[0];
|
|---|
| 883 | REAL t1 = pts[0].param[1];
|
|---|
| 884 | REAL s2 = pts[1].param[0];
|
|---|
| 885 | REAL t2 = pts[1].param[1];
|
|---|
| 886 |
|
|---|
| 887 | jarc->pwlArc->deleteMe( pwlarcpool ); jarc->pwlArc = 0;
|
|---|
| 888 |
|
|---|
| 889 | switch( jarc->getside() ) {
|
|---|
| 890 | case arc_left:
|
|---|
| 891 | assert( s1 == s2 );
|
|---|
| 892 | arctessellator.pwl_left( jarc, s1, t1, t2, lrate );
|
|---|
| 893 | break;
|
|---|
| 894 | case arc_right:
|
|---|
| 895 | assert( s1 == s2 );
|
|---|
| 896 | arctessellator.pwl_right( jarc, s1, t1, t2, rrate );
|
|---|
| 897 | break;
|
|---|
| 898 | case arc_top:
|
|---|
| 899 | assert( t1 == t2 );
|
|---|
| 900 | arctessellator.pwl_top( jarc, t1, s1, s2, trate );
|
|---|
| 901 | break;
|
|---|
| 902 | case arc_bottom:
|
|---|
| 903 | assert( t1 == t2 );
|
|---|
| 904 | arctessellator.pwl_bottom( jarc, t1, s1, s2, brate );
|
|---|
| 905 | break;
|
|---|
| 906 | case arc_none:
|
|---|
| 907 | (void) abort();
|
|---|
| 908 | break;
|
|---|
| 909 | }
|
|---|
| 910 | assert( ! jarc->isbezier() );
|
|---|
| 911 | assert( jarc->check() != 0 );
|
|---|
| 912 | }
|
|---|
| 913 | }
|
|---|
| 914 | }
|
|---|