/*
** License Applicability. Except to the extent portions of this file are
** made subject to an alternative license as permitted in the SGI Free
** Software License B, Version 1.1 (the "License"), the contents of this
** file are subject only to the provisions of the License. You may not use
** this file except in compliance with the License. You may obtain a copy
** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
**
** http://oss.sgi.com/projects/FreeB
**
** Note that, as provided in the License, the Software is distributed on an
** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
**
** Original Code. The Original Code is: OpenGL Sample Implementation,
** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
** Copyright in any portions created by third parties is as indicated
** elsewhere herein. All Rights Reserved.
**
** Additional Notice Provisions: The application programming interfaces
** established by SGI in conjunction with the Original Code are The
** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
** Window System(R) (Version 1.3), released October 19, 1998. This software
** was created using the OpenGL(R) version 1.2.1 Sample Implementation
** published by SGI, but has not been independently verified as being
** compliant with the OpenGL(R) version 1.2.1 Specification.
*/

/*
 * monotonizer.c++
 *
 * $Date: 2012/03/29 17:22:18 $ $Revision: 1.1.1.1 $
 * $Header: /cvs/bao-parsec/pkgs/libs/mesa/src/src/glu/sgi/libnurbs/internals/monotonizer.cc,v 1.1.1.1 2012/03/29 17:22:18 uid42307 Exp $
 */

#include "glimports.h"
#include "mystdio.h"
#include "myassert.h"
#include "arc.h"
#include "arctess.h"
#include "bezierarc.h"
#include "bin.h"
#include "mapdesc.h"
#include "nurbsconsts.h"
#include "subdivider.h"

/*-----------------------------------------------------------------------------
 * Subdivider::decompose - break all curves into monotone arcs
 *-----------------------------------------------------------------------------
 */
int
Subdivider::decompose( Bin& bin, REAL geo_stepsize )
{
    Arc_ptr jarc;
    for( jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) {
	if( ! jarc->isTessellated() ) {
	    /* points have not been transformed, therefore they may be either
	       homogeneous or inhomogeneous */
	    tessellate( jarc, geo_stepsize );
	    if( jarc->isDisconnected() || jarc->next->isDisconnected() ) 
		return 1;
	}
    }

    for( jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) {
	monotonize( jarc, bin );
    }

#ifndef NDEBUG
    for( jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) {
	assert( isMonotone( jarc ) != 0 );
    }
#endif

    return 0;
}

void
Subdivider::tessellate( Arc_ptr jarc, REAL geo_stepsize )
{
    BezierArc *b = jarc->bezierArc;
    Mapdesc *mapdesc = b->mapdesc;

    if( mapdesc->isRational() ) {
	REAL max = mapdesc->calcVelocityRational( b->cpts, b->stride, b->order );
	REAL arc_stepsize = (max > 1.0) ? (1.0/max) : 1.0; 
	if( jarc->bezierArc->order != 2 )
	    arctessellator.tessellateNonlinear( jarc, geo_stepsize, arc_stepsize, 1 );
	else {
	    arctessellator.tessellateLinear( jarc, geo_stepsize, arc_stepsize, 1 );
	}
    } else { 
	REAL max = mapdesc->calcVelocityNonrational( b->cpts, b->stride, b->order );
	REAL arc_stepsize = (max > 1.0) ? (1.0/max) : 1.0; 
	if( jarc->bezierArc->order != 2 )
	    arctessellator.tessellateNonlinear( jarc, geo_stepsize, arc_stepsize, 0 );
	else {
	    arctessellator.tessellateLinear( jarc, geo_stepsize, arc_stepsize, 0 );
	}
    }
}

/*-------------------------------------------------------------------------
 * Subdivider::monotonize - break up a jordan arc into s,t-monotone
 *	components.  This code will remove degenerate segments, including
 *	arcs of only a single point.
 *-------------------------------------------------------------------------
 */
void
Subdivider::monotonize( Arc_ptr jarc, Bin& bin )
{
    TrimVertex  *firstvert = jarc->pwlArc->pts;
    TrimVertex  *lastvert = firstvert + (jarc->pwlArc->npts - 1);
    long	uid = jarc->nuid;
    arc_side	side = jarc->getside();
    dir		sdir = none;
    dir		tdir = none;
    int 	degenerate = 1;

    int		nudegenerate;
    int		change;

    TrimVertex *vert;
    for( vert = firstvert; vert != lastvert; vert++ ) {

        nudegenerate = 1;
        change = 0;

	/* check change relative to s axis, clear degenerate bit if needed */
        REAL sdiff = vert[1].param[0] - vert[0].param[0]; 
        if( sdiff == 0 ) {
	    if( sdir != same ) {
	        sdir = same;
		change = 1;
	    }
        } else if( sdiff < 0.0 ) {
	    if( sdir != down ) {
	        sdir = down;
		change = 1;
	    }
	    nudegenerate = 0;
        } else {
	    if( sdir != up ) {
	        sdir = up;
		change = 1;
	    }
	    nudegenerate = 0;
        }
    
	/* check change relative to t axis, clear degenerate bit if needed */
        REAL tdiff = vert[1].param[1] - vert[0].param[1]; 
        if( tdiff == 0 ) { 
	    if( tdir != same ) {
	        tdir = same;
	 	change = 1;
	    }
        } else if( tdiff < 0.0 ) {
	    if( tdir != down ) {
	        tdir = down;
		change = 1;
	    }
	    nudegenerate = 0;
        } else {
	    if( tdir != up ) {
	        tdir = up;
		change = 1;
	    }
	    nudegenerate = 0;
        }
    
	if( change ) {
	    if( ! degenerate ) {
	        /* make last segment into separate pwl curve */
	        jarc->pwlArc->npts = vert - firstvert + 1;
	        jarc = (new(arcpool) Arc( side, uid ))->append( jarc );
	        jarc->pwlArc = new(pwlarcpool) PwlArc();
		bin.addarc( jarc );
	    }
	    firstvert = jarc->pwlArc->pts = vert;
	    degenerate = nudegenerate;
	} 
    }
    jarc->pwlArc->npts = vert - firstvert + 1;

    if( degenerate ) {
	/* remove jarc from circularly linked list */
	jarc->prev->next = jarc->next;
	jarc->next->prev = jarc->prev;

        assert( jarc->prev->check(  ) != 0 );
        assert( jarc->next->check(  ) != 0 );

	/* remove jarc from bin */
	bin.remove_this_arc( jarc  );

	jarc->pwlArc->deleteMe( pwlarcpool ); jarc->pwlArc = 0;
	jarc->deleteMe( arcpool );
    } 
}

/*-------------------------------------------------------------------------
 * Subdivider::isMonotone - return true if arc is monotone AND non-degenerate
 *-------------------------------------------------------------------------
 */
int
Subdivider::isMonotone( Arc_ptr jarc )
{
    TrimVertex  *firstvert = jarc->pwlArc->pts;
    TrimVertex  *lastvert = firstvert + (jarc->pwlArc->npts - 1);

    if( firstvert == lastvert ) return 1;

    TrimVertex	*vert = firstvert;
    enum dir	sdir;
    enum dir	tdir;

    REAL diff = vert[1].param[0] - vert[0].param[0]; 
    if( diff == 0.0 ) 
        sdir = same;
    else if( diff < 0.0 )
        sdir = down;
    else
        sdir = up;

    diff = vert[1].param[1] - vert[0].param[1]; 
    if( diff == 0.0 ) 
        tdir = same;
    else if( diff < 0.0 )
        tdir = down;
    else
        tdir = up;

    if( (sdir == same) && (tdir == same) ) return 0;
    
    for( ++vert ; vert != lastvert; vert++ ) {
        diff = vert[1].param[0] - vert[0].param[0]; 
        if( diff == 0.0 ) {
	    if( sdir != same ) return 0;
        } else if( diff < 0.0 ) {
	    if( sdir != down ) return 0;
        } else {
	    if( sdir != up ) return 0;
        }

        diff = vert[1].param[1] - vert[0].param[1]; 
        if( diff == 0.0 ) {
	    if( tdir != same ) return 0;
        } else if( diff < 0.0 ) {
	    if( tdir != down ) return 0;
        } else {
	    if( tdir != up ) return 0;
        }
    }
    return 1;
}

