/* $Id: nurbs.h,v 1.2 1999/11/11 03:21:43 kendallb Exp $ */

/*
 * Mesa 3-D graphics library
 * Version:  3.1
 * Copyright (C) 1995-1999  Brian Paul
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */


/*
 * $Log: nurbs.h,v $
 * Revision 1.2  1999/11/11 03:21:43  kendallb
 *
 *  . Updated GL/gl.h with GLCALLACKP and GLAPIENTRYP macros for compatibility
 *    with the IBM VisualAge C++ compiler. Eventually some more code will be
 *    needed in the headers to enable the reversal of (__stdcall*) to (*__stdcall)
 *    for the IBM compilers, however we currently build using our own header files
 *    that already handle this.
 *
 *  . Changed instances of (GLCALLBACK*) to GLCALLBACKP for compatibility
 *    with the IBM VisualAge C++ compiler in src-glu.
 *
 *  . Misc cleanups for warnings generated with Watcom C++ in src-glu. Compiles
 *    with 0 warnings now.
 *
 *  . tess_hash.c: line 244 - Why is this function stubbed out? I removed the
 *    code with a #if 0 to avoid a compiler warning, but it looks dangerous.
 *
 * Revision 1.1.1.1  1999/08/19 00:55:42  jtg
 * Imported sources
 *
 * Revision 1.5  1999/02/27 13:55:31  brianp
 * fixed BeOS-related GLU typedef problems
 *
 * Revision 1.4  1999/01/03 03:23:15  brianp
 * now using GLAPIENTRY and GLCALLBACK keywords (Ted Jump)
 *
 * Revision 1.3  1997/05/27 03:18:23  brianp
 * minor clean-up
 *
 * Revision 1.2  1997/05/27 03:00:16  brianp
 * incorporated Bogdan's new NURBS code
 *
 * Revision 1.1  1996/09/27 01:19:39  brianp
 * Initial revision
 *
 */


/*
 * NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
 * See README2 for more info.
 */


#ifndef NURBS_H
#define NURBS_H


#define EPSILON 1e-06 /* epsilon for double precision compares */

typedef enum
{
	GLU_NURBS_CURVE, GLU_NURBS_SURFACE, GLU_NURBS_TRIM, GLU_NURBS_NO_TRIM,
	GLU_NURBS_TRIM_DONE, GLU_NURBS_NONE
} GLU_nurbs_enum;

typedef enum
{
	GLU_TRIM_NURBS, GLU_TRIM_PWL
} GLU_trim_enum;

typedef struct
{
	GLint	sknot_count;
	GLfloat	*sknot;
	GLint	tknot_count;
	GLfloat	*tknot;
	GLint	s_stride;
	GLint	t_stride;
	GLfloat	*ctrlarray;
	GLint	sorder;
	GLint	torder;
	GLint	dim;
	GLenum	type;
} surface_attribs;

typedef struct
{
	surface_attribs	geom;
	surface_attribs	color;
	surface_attribs	texture;
	surface_attribs	normal;
} nurbs_surface;

typedef struct
{
	GLint			knot_count;
	GLfloat			*knot;
	GLint			stride;
	GLfloat			*ctrlarray;
	GLint			order;
	GLint			dim;
	GLenum			type;
} curve_attribs;

typedef struct
{
	GLint			pt_count;
	GLfloat			*ctrlarray;
	GLint			stride;
	GLint			dim;
	GLenum			type;
} pwl_curve_attribs;

typedef struct
{
	curve_attribs	geom;
	curve_attribs	color;
	curve_attribs	texture;
	curve_attribs	normal;
} nurbs_curve;

typedef struct trim_list_str
{
	GLU_trim_enum			trim_type;
	union
	{
		pwl_curve_attribs	pwl_curve;
		curve_attribs		nurbs_curve;
	}						curve;
	struct trim_list_str	*next;
} trim_list;

typedef struct seg_trim_str
{
	GLfloat 			*points;
	GLint				pt_cnt,seg_array_len;
	struct seg_trim_str	*next;
} trim_segments;

typedef struct nurbs_trim_str
{
	trim_list				*trim_loop;
	trim_segments			*segments;
	struct nurbs_trim_str	*next;
} nurbs_trim;

typedef struct
{
	GLfloat model[16],proj[16],viewport[4];
} culling_and_sampling_str;

struct GLUnurbs {
	GLboolean		culling;
	GLenum			error;
	void			(GLCALLBACKP error_callback)( GLenum err );
	GLenum			display_mode;
	GLU_nurbs_enum	nurbs_type;
	GLboolean		auto_load_matrix;
	culling_and_sampling_str
					sampling_matrices;
	GLenum			sampling_method;
	GLfloat			sampling_tolerance;
	GLfloat			parametric_tolerance;
	GLint			u_step, v_step;
	nurbs_surface	surface;
	nurbs_curve		curve;
	nurbs_trim		*trim;
};

typedef struct
{
	GLfloat		*knot;
	GLint		nknots;
	GLfloat		*unified_knot;
	GLint		unified_nknots;
	GLint		order;
	GLint		t_min,t_max;
	GLint		delta_nknots;
	GLboolean	open_at_begin,open_at_end;
	GLfloat		*new_knot;
	GLfloat		*alpha;
} knot_str_type;

typedef struct
{
	GLfloat	*geom_ctrl;
	GLint	geom_s_stride,geom_t_stride;
	GLfloat	**geom_offsets;
	GLint	geom_s_pt_cnt,geom_t_pt_cnt;
	GLfloat	*color_ctrl;
	GLint	color_s_stride,color_t_stride;
	GLfloat	**color_offsets;
	GLint	color_s_pt_cnt,color_t_pt_cnt;
	GLfloat *normal_ctrl;
	GLint	normal_s_stride,normal_t_stride;
	GLfloat	**normal_offsets;
	GLint	normal_s_pt_cnt,normal_t_pt_cnt;
	GLfloat	*texture_ctrl;
	GLint	texture_s_stride,texture_t_stride;
	GLfloat	**texture_offsets;
	GLint	texture_s_pt_cnt,texture_t_pt_cnt;
	GLint	s_bezier_cnt,t_bezier_cnt;
} new_ctrl_type;

extern void call_user_error( GLUnurbsObj *nobj, GLenum error );

extern GLenum test_knot(GLint nknots, GLfloat *knot, GLint order);

extern GLenum explode_knot(knot_str_type *the_knot);

extern GLenum calc_alphas(knot_str_type *the_knot);

extern GLenum calc_new_ctrl_pts(GLfloat *ctrl,GLint stride,knot_str_type *the_knot,
	GLint dim,GLfloat **new_ctrl,GLint *ncontrol);

extern GLenum glu_do_sampling_crv(GLUnurbsObj *nobj, GLfloat *new_ctrl,GLint n_ctrl,
	GLint order,GLint dim,GLint **factors);

extern GLenum glu_do_sampling_3D(GLUnurbsObj *nobj, new_ctrl_type *new_ctrl,
	int **sfactors, GLint **tfactors);

extern GLenum glu_do_sampling_uv(GLUnurbsObj *nobj, new_ctrl_type *new_ctrl,
	int **sfactors, GLint **tfactors);

extern GLenum glu_do_sampling_param_3D(GLUnurbsObj *nobj, new_ctrl_type *new_ctrl,
	int **sfactors, GLint **tfactors);

extern GLboolean fine_culling_test_2D(GLUnurbsObj *nobj, GLfloat *ctrl, GLint n_ctrl,
	GLint stride, GLint dim);

extern GLboolean fine_culling_test_3D(GLUnurbsObj *nobj, GLfloat *ctrl,
	GLint s_n_ctrl, GLint t_n_ctrl, GLint s_stride, GLint t_stride, GLint dim);

extern void do_nurbs_curve( GLUnurbsObj *nobj);

extern void do_nurbs_surface( GLUnurbsObj *nobj);

extern GLenum patch_trimming(GLUnurbsObj *nobj,new_ctrl_type *new_ctrl,
	GLint *sfactors, GLint *tfactors);

extern void collect_unified_knot(knot_str_type *dest, knot_str_type *src,
	GLfloat maximal_min_knot, GLfloat minimal_max_knot);

extern GLenum select_knot_working_range(GLUnurbsObj *nobj,knot_str_type *geom_knot,
	knot_str_type *color_knot, knot_str_type *normal_knot,
	knot_str_type *texture_knot);

extern void free_unified_knots(knot_str_type *geom_knot, knot_str_type *color_knot,
	knot_str_type *normal_knot, knot_str_type *texture_knot);



#endif
