# Directories to build
LIB_DIR = lib
SRC_DIRS = glsl mapi/glapi mapi/vgapi mesa \
- gallium egl gallium/winsys gallium/targets glu
+ gallium egl gallium/winsys gallium/targets
DRIVER_DIRS = x11 osmesa
# Gallium directories and
[specify GL library name @<:@default=GL@:>@])],
[GL_LIB=$withval],
[GL_LIB=GL])
-AC_ARG_WITH([glu-lib-name],
- [AS_HELP_STRING([--with-glu-lib-name@<:@=NAME@:>@],
- [specify GLU library name @<:@default=GLU@:>@])],
- [GLU_LIB=$withval],
- [GLU_LIB=GLU])
AC_ARG_WITH([osmesa-lib-name],
[AS_HELP_STRING([--with-osmesa-lib-name@<:@=NAME@:>@],
[specify OSMesa library name @<:@default=OSMesa@:>@])],
[OSMESA_LIB=$withval],
[OSMESA_LIB=OSMesa])
AS_IF([test "x$GL_LIB" = xyes], [GL_LIB=GL])
-AS_IF([test "x$GLU_LIB" = xyes], [GLU_LIB=GLU])
AS_IF([test "x$OSMESA_LIB" = xyes], [OSMESA_LIB=OSMesa])
dnl
if test "x${enable_mangling}" = "xyes" ; then
DEFINES="${DEFINES} -DUSE_MGL_NAMESPACE"
GL_LIB="Mangled${GL_LIB}"
- GLU_LIB="Mangled${GLU_LIB}"
OSMESA_LIB="Mangled${OSMESA_LIB}"
fi
AC_SUBST([GL_LIB])
-AC_SUBST([GLU_LIB])
AC_SUBST([OSMESA_LIB])
dnl
fi
GL_LIB_NAME='lib$(GL_LIB).'${LIB_EXTENSION}
-GLU_LIB_NAME='lib$(GLU_LIB).'${LIB_EXTENSION}
OSMESA_LIB_NAME='lib$(OSMESA_LIB).'${LIB_EXTENSION}
EGL_LIB_NAME='lib$(EGL_LIB).'${LIB_EXTENSION}
GLESv1_CM_LIB_NAME='lib$(GLESv1_CM_LIB).'${LIB_EXTENSION}
GLAPI_LIB_NAME='lib$(GLAPI_LIB).'${LIB_EXTENSION}
GL_LIB_GLOB=${LIB_PREFIX_GLOB}'$(GL_LIB)'${LIB_VERSION_SEPARATOR}'*'${LIB_EXTENSION}'*'
-GLU_LIB_GLOB=${LIB_PREFIX_GLOB}'$(GLU_LIB)'${LIB_VERSION_SEPARATOR}'*'${LIB_EXTENSION}'*'
EGL_LIB_GLOB=${LIB_PREFIX_GLOB}'$(EGL_LIB)'${LIB_VERSION_SEPARATOR}'*'${LIB_EXTENSION}'*'
EGL_LIB_GLOB=${LIB_PREFIX_GLOB}'$(EGL_LIB)'${LIB_VERSION_SEPARATOR}'*'${LIB_EXTENSION}'*'
GLESv1_CM_LIB_GLOB=${LIB_PREFIX_GLOB}'$(GLESv1_CM_LIB)'${LIB_VERSION_SEPARATOR}'*'${LIB_EXTENSION}'*'
GLAPI_LIB_GLOB=${LIB_PREFIX_GLOB}'$(GLAPI_LIB)'${LIB_VERSION_SEPARATOR}'*'${LIB_EXTENSION}'*'
AC_SUBST([GL_LIB_NAME])
-AC_SUBST([GLU_LIB_NAME])
AC_SUBST([OSMESA_LIB_NAME])
AC_SUBST([EGL_LIB_NAME])
AC_SUBST([GLESv1_CM_LIB_NAME])
AC_SUBST([GLAPI_LIB_NAME])
AC_SUBST([GL_LIB_GLOB])
-AC_SUBST([GLU_LIB_GLOB])
AC_SUBST([EGL_LIB_GLOB])
AC_SUBST([GLESv1_CM_LIB_GLOB])
AC_SUBST([GLESv2_LIB_GLOB])
enable_gallium_loader=yes
fi
-dnl
-dnl GLU configuration
-dnl
-AC_ARG_ENABLE([glu],
- [AS_HELP_STRING([--disable-glu],
- [enable OpenGL Utility library @<:@default=enabled@:>@])],
- [enable_glu="$enableval"],
- [enable_glu=yes])
-
-if test "x$enable_glu" = xyes; then
- if test "x$enable_glx" = xno -a "x$enable_osmesa" = xno; then
- AC_MSG_NOTICE([Disabling GLU since there is no OpenGL driver])
- enable_glu=no
- fi
-fi
-
-if test "x$enable_glu" = xyes; then
- SRC_DIRS="$SRC_DIRS glu"
-
- if test "x$enable_glx" = xno; then
- # Link libGLU to libOSMesa instead of libGL
- GLU_LIB_DEPS=""
- GLU_PC_REQ="osmesa"
- if test "$enable_static" = no; then
- GLU_MESA_DEPS='-l$(OSMESA_LIB)'
- else
- GLU_MESA_DEPS=""
- fi
- else
- # If static, empty GLU_LIB_DEPS and add libs for programs to link
- GLU_PC_REQ="gl"
- GLU_PC_LIB_PRIV="-lm"
- if test "$enable_static" = no; then
- GLU_LIB_DEPS="-lm"
- GLU_MESA_DEPS='-l$(GL_LIB)'
- else
- GLU_LIB_DEPS=""
- GLU_MESA_DEPS=""
- fi
- fi
-fi
-if test "$enable_static" = no; then
- GLU_LIB_DEPS="$GLU_LIB_DEPS $OS_CPLUSPLUS_LIBS"
-fi
-GLU_PC_LIB_PRIV="$GLU_PC_LIB_PRIV $OS_CPLUSPLUS_LIBS"
-AC_SUBST([GLU_LIB_DEPS])
-AC_SUBST([GLU_MESA_DEPS])
-AC_SUBST([GLU_PC_REQ])
-AC_SUBST([GLU_PC_REQ_PRIV])
-AC_SUBST([GLU_PC_LIB_PRIV])
-AC_SUBST([GLU_PC_CFLAGS])
-
-AC_SUBST([PROGRAM_DIRS])
-
dnl
dnl Gallium configuration
dnl
esac
echo ""
-echo " GLU: $enable_glu"
dnl EGL
echo ""
<li><a href="#dri">DRI Driver Options</a></li>
<li><a href="#osmesa">OSMesa Driver Options</a></li>
</ul>
-<li><p><a href="#library">Library Options</a>
- <ul>
- <li><a href="#glu">GLU</a></li>
- </ul>
<li><p><a href="#demos">Demo Program Options</a>
</ol>
can be found in the <a href="install.html">basic installation
instructions</a>.
-<dl>
-<dt id="glu">GLU <dd><p> The libGLU library will be built by default
-on all drivers. This can be disable with the option
-<code>--disable-glu</code>.
-</dl>
-
<h2 id="demos">4. Demo Program Options</h2>
<li><a href="http://sourceforge.net/projects/mesa3d" target="_parent">SourceForge homepage</a>
<li><a href="repository.html" target="MainFrame">Source Code Repository</a>
<li><a href="sourcetree.html" target="MainFrame">Source Code Tree</a>
-<li><a href="glu.html" target="MainFrame">SGI's GLU</a>
<li><a href="utilities.html" target="MainFrame">Utilities</a>
<li><a href="helpwanted.html" target="MainFrame">Help Wanted</a>
<li><a href="devinfo.html" target="MainFrame">Development Notes</a>
src/ - source code for libraries
src/mesa - sources for the main Mesa library and device drivers
src/gallium - sources for Gallium and Gallium drivers
-src/glu - libGLU source code
src/glx - sources for building libGL with full GLX and DRI support
</pre>
</p>
-<h1>Demos and GLUT</h1>
+<h1>Demos, GLUT, and GLU</h1>
+
+<p>
+A package of SGI's GLU library is available
+<a href="ftp://ftp.freedesktop.org/pub/mesa/glu/" target="_parent">here</a>
+</p>
<p>
A package of Mark Kilgard's GLUT library is available
</p>
<p>
-In the past, GLUT and the Mesa demos were released in conjunction with
-Mesa releases. But since GLUT and the demos change infrequently, they
-were split off some time ago.
+In the past, GLUT, GLU and the Mesa demos were released in conjunction with
+Mesa releases. But since GLUT, GLU and the demos change infrequently, they
+were split off into their own git repositories:
+
+<a href="http://cgit.freedesktop.org/mesa/glut/">GLUT</a>,
+<a href="http://cgit.freedesktop.org/mesa/glu/">GLU</a> and
+<a href="http://cgit.freedesktop.org/mesa/demos/">Demos</a>,
</p>
</li><li>/usr/lib/libGL.so.1 - a symlink to libGL.so.1.xyz
</li><li>/usr/lib/libGL.so.xyz - the actual OpenGL/Mesa library. xyz denotes the
Mesa version number.
-</li><li>/usr/lib/libGLU.so - a symlink to libGLU.so.1
-</li><li>/usr/lib/libGLU.so.1 - a symlink to libGLU.so.1.3.xyz
-</li><li>/usr/lib/libGLU.so.xyz - the OpenGL Utility library. xyz denotes the Mesa
-version number.
</li></ul>
<p>
After installing XFree86/X.org and the DRI drivers, some of these files
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html lang="en">
-<head>
- <meta http-equiv="content-type" content="text/html; charset=utf-8">
- <title>SGI GLU</title>
- <link rel="stylesheet" type="text/css" href="mesa.css">
-</head>
-<body>
-
-<h1>SGI SI GLU</h1>
-
-(Silicon Graphics, Inc. Sample Implementation of the OpenGL Utility library)
-
-<p>
-SGI open-sourced their OpenGL Sample Implementation (SI) in January, 2000.
-This includes the GLU library.
-</p>
-
-<p>
-The SI GLU library implements GLU version 1.3 whereas the original
-Mesa GLU library only implemented version 1.2.
-We recommend using the SI GLU library instead of Mesa's GLU library
-since it's more up-to-date, complete and reliable.
-We're no longer developing the original Mesa GLU library.
-</p>
-
-<p>
-The SI GLU library code is included in the Mesa distribution.
-You don't have to download it separately.
-</p>
-
-
-<p>
-<b>Olivier Michel</b> has made Linux RPMs of GLU for i386 and PowerPC.
-You can download them from the
-<a href="http://www.sourceforge.net/project/showfiles.php?group_id=3"
-target="_parent">download area</a> under <b>Miscellaneous</b>.
-</p>
-
-<p>
-Visit the <a href="http://oss.sgi.com/projects/ogl-sample/" target="_parent">
-OpenGL Sample Implementation home page</a> for more information about the SI.
-</p>
-
-</body>
-</html>
lrwxrwxrwx 1 brian users 10 Mar 26 07:53 libGL.so -> libGL.so.1*
lrwxrwxrwx 1 brian users 19 Mar 26 07:53 libGL.so.1 -> libGL.so.1.5.060100*
-rwxr-xr-x 1 brian users 3375861 Mar 26 07:53 libGL.so.1.5.060100*
-lrwxrwxrwx 1 brian users 11 Mar 26 07:53 libGLU.so -> libGLU.so.1*
-lrwxrwxrwx 1 brian users 20 Mar 26 07:53 libGLU.so.1 -> libGLU.so.1.3.060100*
--rwxr-xr-x 1 brian users 549269 Mar 26 07:53 libGLU.so.1.3.060100*
lrwxrwxrwx 1 brian users 14 Mar 26 07:53 libOSMesa.so -> libOSMesa.so.6*
lrwxrwxrwx 1 brian users 23 Mar 26 07:53 libOSMesa.so.6 -> libOSMesa.so.6.1.060100*
-rwxr-xr-x 1 brian users 23871 Mar 26 07:53 libOSMesa.so.6.1.060100*
<p>
<b>libGL</b> is the main OpenGL library (i.e. Mesa).
<br>
-<b>libGLU</b> is the OpenGL Utility library.
-<br>
<b>libOSMesa</b> is the OSMesa (Off-Screen) interface library.
</p>
Ext headers include/GL/glext.h Khronos
include/GL/glxext.h
-
-SGI GLU library src/glu/sgi/ SGI Free B
</pre>
<p>
<li>Removed Gallium3D - nvfx driver (use nv30 instead)</li>
</ul>
+<p>
+libGLU has been moved into its own repository, found at <a href="http://cgit.freedesktop.org/mesa/glu/">http://cgit.freedesktop.org/mesa/glu/</a>
+</p>
+
</body>
</html>
</ul>
</ul>
<ul>
- <li><b>glu</b> - The OpenGL Utility library
- <ul>
- <li><b>sgi</b> - GLU from SGI
- <li><b>mesa</b> - Mesa version of GLU (deprecated)
- </ul>
<li><b>glx</b> - The GLX library code for building libGL. This is used for
direct rendering drivers. It will dynamically load one of the
xxx_dri.so drivers.
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#ifndef __glu_h__
-#define __glu_h__
-
-#if defined(USE_MGL_NAMESPACE)
-#include "glu_mangle.h"
-#endif
-
-#include <GL/gl.h>
-
-#ifndef GLAPIENTRY
-#if defined(_MSC_VER) || defined(__MINGW32__)
-#define GLAPIENTRY __stdcall
-#else
-#define GLAPIENTRY
-#endif
-#endif
-
-#ifndef GLAPIENTRYP
-#define GLAPIENTRYP GLAPIENTRY *
-#endif
-
-#if (defined(_MSC_VER) || defined(__MINGW32__)) && defined(BUILD_GLU32)
-# undef GLAPI
-# define GLAPI __declspec(dllexport)
-#elif (defined(_MSC_VER) || defined(__MINGW32__)) && defined(_DLL)
-/* tag specifying we're building for DLL runtime support */
-# undef GLAPI
-# define GLAPI __declspec(dllimport)
-#elif !defined(GLAPI)
-/* for use with static link lib build of Win32 edition only */
-# define GLAPI extern
-#endif /* _STATIC_MESA support */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*************************************************************/
-
-/* Extensions */
-#define GLU_EXT_object_space_tess 1
-#define GLU_EXT_nurbs_tessellator 1
-
-/* Boolean */
-#define GLU_FALSE 0
-#define GLU_TRUE 1
-
-/* Version */
-#define GLU_VERSION_1_1 1
-#define GLU_VERSION_1_2 1
-#define GLU_VERSION_1_3 1
-
-/* StringName */
-#define GLU_VERSION 100800
-#define GLU_EXTENSIONS 100801
-
-/* ErrorCode */
-#define GLU_INVALID_ENUM 100900
-#define GLU_INVALID_VALUE 100901
-#define GLU_OUT_OF_MEMORY 100902
-#define GLU_INCOMPATIBLE_GL_VERSION 100903
-#define GLU_INVALID_OPERATION 100904
-
-/* NurbsDisplay */
-/* GLU_FILL */
-#define GLU_OUTLINE_POLYGON 100240
-#define GLU_OUTLINE_PATCH 100241
-
-/* NurbsCallback */
-#define GLU_NURBS_ERROR 100103
-#define GLU_ERROR 100103
-#define GLU_NURBS_BEGIN 100164
-#define GLU_NURBS_BEGIN_EXT 100164
-#define GLU_NURBS_VERTEX 100165
-#define GLU_NURBS_VERTEX_EXT 100165
-#define GLU_NURBS_NORMAL 100166
-#define GLU_NURBS_NORMAL_EXT 100166
-#define GLU_NURBS_COLOR 100167
-#define GLU_NURBS_COLOR_EXT 100167
-#define GLU_NURBS_TEXTURE_COORD 100168
-#define GLU_NURBS_TEX_COORD_EXT 100168
-#define GLU_NURBS_END 100169
-#define GLU_NURBS_END_EXT 100169
-#define GLU_NURBS_BEGIN_DATA 100170
-#define GLU_NURBS_BEGIN_DATA_EXT 100170
-#define GLU_NURBS_VERTEX_DATA 100171
-#define GLU_NURBS_VERTEX_DATA_EXT 100171
-#define GLU_NURBS_NORMAL_DATA 100172
-#define GLU_NURBS_NORMAL_DATA_EXT 100172
-#define GLU_NURBS_COLOR_DATA 100173
-#define GLU_NURBS_COLOR_DATA_EXT 100173
-#define GLU_NURBS_TEXTURE_COORD_DATA 100174
-#define GLU_NURBS_TEX_COORD_DATA_EXT 100174
-#define GLU_NURBS_END_DATA 100175
-#define GLU_NURBS_END_DATA_EXT 100175
-
-/* NurbsError */
-#define GLU_NURBS_ERROR1 100251
-#define GLU_NURBS_ERROR2 100252
-#define GLU_NURBS_ERROR3 100253
-#define GLU_NURBS_ERROR4 100254
-#define GLU_NURBS_ERROR5 100255
-#define GLU_NURBS_ERROR6 100256
-#define GLU_NURBS_ERROR7 100257
-#define GLU_NURBS_ERROR8 100258
-#define GLU_NURBS_ERROR9 100259
-#define GLU_NURBS_ERROR10 100260
-#define GLU_NURBS_ERROR11 100261
-#define GLU_NURBS_ERROR12 100262
-#define GLU_NURBS_ERROR13 100263
-#define GLU_NURBS_ERROR14 100264
-#define GLU_NURBS_ERROR15 100265
-#define GLU_NURBS_ERROR16 100266
-#define GLU_NURBS_ERROR17 100267
-#define GLU_NURBS_ERROR18 100268
-#define GLU_NURBS_ERROR19 100269
-#define GLU_NURBS_ERROR20 100270
-#define GLU_NURBS_ERROR21 100271
-#define GLU_NURBS_ERROR22 100272
-#define GLU_NURBS_ERROR23 100273
-#define GLU_NURBS_ERROR24 100274
-#define GLU_NURBS_ERROR25 100275
-#define GLU_NURBS_ERROR26 100276
-#define GLU_NURBS_ERROR27 100277
-#define GLU_NURBS_ERROR28 100278
-#define GLU_NURBS_ERROR29 100279
-#define GLU_NURBS_ERROR30 100280
-#define GLU_NURBS_ERROR31 100281
-#define GLU_NURBS_ERROR32 100282
-#define GLU_NURBS_ERROR33 100283
-#define GLU_NURBS_ERROR34 100284
-#define GLU_NURBS_ERROR35 100285
-#define GLU_NURBS_ERROR36 100286
-#define GLU_NURBS_ERROR37 100287
-
-/* NurbsProperty */
-#define GLU_AUTO_LOAD_MATRIX 100200
-#define GLU_CULLING 100201
-#define GLU_SAMPLING_TOLERANCE 100203
-#define GLU_DISPLAY_MODE 100204
-#define GLU_PARAMETRIC_TOLERANCE 100202
-#define GLU_SAMPLING_METHOD 100205
-#define GLU_U_STEP 100206
-#define GLU_V_STEP 100207
-#define GLU_NURBS_MODE 100160
-#define GLU_NURBS_MODE_EXT 100160
-#define GLU_NURBS_TESSELLATOR 100161
-#define GLU_NURBS_TESSELLATOR_EXT 100161
-#define GLU_NURBS_RENDERER 100162
-#define GLU_NURBS_RENDERER_EXT 100162
-
-/* NurbsSampling */
-#define GLU_OBJECT_PARAMETRIC_ERROR 100208
-#define GLU_OBJECT_PARAMETRIC_ERROR_EXT 100208
-#define GLU_OBJECT_PATH_LENGTH 100209
-#define GLU_OBJECT_PATH_LENGTH_EXT 100209
-#define GLU_PATH_LENGTH 100215
-#define GLU_PARAMETRIC_ERROR 100216
-#define GLU_DOMAIN_DISTANCE 100217
-
-/* NurbsTrim */
-#define GLU_MAP1_TRIM_2 100210
-#define GLU_MAP1_TRIM_3 100211
-
-/* QuadricDrawStyle */
-#define GLU_POINT 100010
-#define GLU_LINE 100011
-#define GLU_FILL 100012
-#define GLU_SILHOUETTE 100013
-
-/* QuadricCallback */
-/* GLU_ERROR */
-
-/* QuadricNormal */
-#define GLU_SMOOTH 100000
-#define GLU_FLAT 100001
-#define GLU_NONE 100002
-
-/* QuadricOrientation */
-#define GLU_OUTSIDE 100020
-#define GLU_INSIDE 100021
-
-/* TessCallback */
-#define GLU_TESS_BEGIN 100100
-#define GLU_BEGIN 100100
-#define GLU_TESS_VERTEX 100101
-#define GLU_VERTEX 100101
-#define GLU_TESS_END 100102
-#define GLU_END 100102
-#define GLU_TESS_ERROR 100103
-#define GLU_TESS_EDGE_FLAG 100104
-#define GLU_EDGE_FLAG 100104
-#define GLU_TESS_COMBINE 100105
-#define GLU_TESS_BEGIN_DATA 100106
-#define GLU_TESS_VERTEX_DATA 100107
-#define GLU_TESS_END_DATA 100108
-#define GLU_TESS_ERROR_DATA 100109
-#define GLU_TESS_EDGE_FLAG_DATA 100110
-#define GLU_TESS_COMBINE_DATA 100111
-
-/* TessContour */
-#define GLU_CW 100120
-#define GLU_CCW 100121
-#define GLU_INTERIOR 100122
-#define GLU_EXTERIOR 100123
-#define GLU_UNKNOWN 100124
-
-/* TessProperty */
-#define GLU_TESS_WINDING_RULE 100140
-#define GLU_TESS_BOUNDARY_ONLY 100141
-#define GLU_TESS_TOLERANCE 100142
-
-/* TessError */
-#define GLU_TESS_ERROR1 100151
-#define GLU_TESS_ERROR2 100152
-#define GLU_TESS_ERROR3 100153
-#define GLU_TESS_ERROR4 100154
-#define GLU_TESS_ERROR5 100155
-#define GLU_TESS_ERROR6 100156
-#define GLU_TESS_ERROR7 100157
-#define GLU_TESS_ERROR8 100158
-#define GLU_TESS_MISSING_BEGIN_POLYGON 100151
-#define GLU_TESS_MISSING_BEGIN_CONTOUR 100152
-#define GLU_TESS_MISSING_END_POLYGON 100153
-#define GLU_TESS_MISSING_END_CONTOUR 100154
-#define GLU_TESS_COORD_TOO_LARGE 100155
-#define GLU_TESS_NEED_COMBINE_CALLBACK 100156
-
-/* TessWinding */
-#define GLU_TESS_WINDING_ODD 100130
-#define GLU_TESS_WINDING_NONZERO 100131
-#define GLU_TESS_WINDING_POSITIVE 100132
-#define GLU_TESS_WINDING_NEGATIVE 100133
-#define GLU_TESS_WINDING_ABS_GEQ_TWO 100134
-
-/*************************************************************/
-
-
-#ifdef __cplusplus
-class GLUnurbs;
-class GLUquadric;
-class GLUtesselator;
-#else
-typedef struct GLUnurbs GLUnurbs;
-typedef struct GLUquadric GLUquadric;
-typedef struct GLUtesselator GLUtesselator;
-#endif
-
-typedef GLUnurbs GLUnurbsObj;
-typedef GLUquadric GLUquadricObj;
-typedef GLUtesselator GLUtesselatorObj;
-typedef GLUtesselator GLUtriangulatorObj;
-
-#define GLU_TESS_MAX_COORD 1.0e150
-
-/* Internal convenience typedefs */
-typedef void (GLAPIENTRYP _GLUfuncptr)(void);
-
-GLAPI void GLAPIENTRY gluBeginCurve (GLUnurbs* nurb);
-GLAPI void GLAPIENTRY gluBeginPolygon (GLUtesselator* tess);
-GLAPI void GLAPIENTRY gluBeginSurface (GLUnurbs* nurb);
-GLAPI void GLAPIENTRY gluBeginTrim (GLUnurbs* nurb);
-GLAPI GLint GLAPIENTRY gluBuild1DMipmapLevels (GLenum target, GLint internalFormat, GLsizei width, GLenum format, GLenum type, GLint level, GLint base, GLint max, const void *data);
-GLAPI GLint GLAPIENTRY gluBuild1DMipmaps (GLenum target, GLint internalFormat, GLsizei width, GLenum format, GLenum type, const void *data);
-GLAPI GLint GLAPIENTRY gluBuild2DMipmapLevels (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint level, GLint base, GLint max, const void *data);
-GLAPI GLint GLAPIENTRY gluBuild2DMipmaps (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data);
-GLAPI GLint GLAPIENTRY gluBuild3DMipmapLevels (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLint level, GLint base, GLint max, const void *data);
-GLAPI GLint GLAPIENTRY gluBuild3DMipmaps (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data);
-GLAPI GLboolean GLAPIENTRY gluCheckExtension (const GLubyte *extName, const GLubyte *extString);
-GLAPI void GLAPIENTRY gluCylinder (GLUquadric* quad, GLdouble base, GLdouble top, GLdouble height, GLint slices, GLint stacks);
-GLAPI void GLAPIENTRY gluDeleteNurbsRenderer (GLUnurbs* nurb);
-GLAPI void GLAPIENTRY gluDeleteQuadric (GLUquadric* quad);
-GLAPI void GLAPIENTRY gluDeleteTess (GLUtesselator* tess);
-GLAPI void GLAPIENTRY gluDisk (GLUquadric* quad, GLdouble inner, GLdouble outer, GLint slices, GLint loops);
-GLAPI void GLAPIENTRY gluEndCurve (GLUnurbs* nurb);
-GLAPI void GLAPIENTRY gluEndPolygon (GLUtesselator* tess);
-GLAPI void GLAPIENTRY gluEndSurface (GLUnurbs* nurb);
-GLAPI void GLAPIENTRY gluEndTrim (GLUnurbs* nurb);
-GLAPI const GLubyte * GLAPIENTRY gluErrorString (GLenum error);
-GLAPI void GLAPIENTRY gluGetNurbsProperty (GLUnurbs* nurb, GLenum property, GLfloat* data);
-GLAPI const GLubyte * GLAPIENTRY gluGetString (GLenum name);
-GLAPI void GLAPIENTRY gluGetTessProperty (GLUtesselator* tess, GLenum which, GLdouble* data);
-GLAPI void GLAPIENTRY gluLoadSamplingMatrices (GLUnurbs* nurb, const GLfloat *model, const GLfloat *perspective, const GLint *view);
-GLAPI void GLAPIENTRY gluLookAt (GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ, GLdouble centerX, GLdouble centerY, GLdouble centerZ, GLdouble upX, GLdouble upY, GLdouble upZ);
-GLAPI GLUnurbs* GLAPIENTRY gluNewNurbsRenderer (void);
-GLAPI GLUquadric* GLAPIENTRY gluNewQuadric (void);
-GLAPI GLUtesselator* GLAPIENTRY gluNewTess (void);
-GLAPI void GLAPIENTRY gluNextContour (GLUtesselator* tess, GLenum type);
-GLAPI void GLAPIENTRY gluNurbsCallback (GLUnurbs* nurb, GLenum which, _GLUfuncptr CallBackFunc);
-GLAPI void GLAPIENTRY gluNurbsCallbackData (GLUnurbs* nurb, GLvoid* userData);
-GLAPI void GLAPIENTRY gluNurbsCallbackDataEXT (GLUnurbs* nurb, GLvoid* userData);
-GLAPI void GLAPIENTRY gluNurbsCurve (GLUnurbs* nurb, GLint knotCount, GLfloat *knots, GLint stride, GLfloat *control, GLint order, GLenum type);
-GLAPI void GLAPIENTRY gluNurbsProperty (GLUnurbs* nurb, GLenum property, GLfloat value);
-GLAPI void GLAPIENTRY gluNurbsSurface (GLUnurbs* nurb, GLint sKnotCount, GLfloat* sKnots, GLint tKnotCount, GLfloat* tKnots, GLint sStride, GLint tStride, GLfloat* control, GLint sOrder, GLint tOrder, GLenum type);
-GLAPI void GLAPIENTRY gluOrtho2D (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top);
-GLAPI void GLAPIENTRY gluPartialDisk (GLUquadric* quad, GLdouble inner, GLdouble outer, GLint slices, GLint loops, GLdouble start, GLdouble sweep);
-GLAPI void GLAPIENTRY gluPerspective (GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
-GLAPI void GLAPIENTRY gluPickMatrix (GLdouble x, GLdouble y, GLdouble delX, GLdouble delY, GLint *viewport);
-GLAPI GLint GLAPIENTRY gluProject (GLdouble objX, GLdouble objY, GLdouble objZ, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble* winX, GLdouble* winY, GLdouble* winZ);
-GLAPI void GLAPIENTRY gluPwlCurve (GLUnurbs* nurb, GLint count, GLfloat* data, GLint stride, GLenum type);
-GLAPI void GLAPIENTRY gluQuadricCallback (GLUquadric* quad, GLenum which, _GLUfuncptr CallBackFunc);
-GLAPI void GLAPIENTRY gluQuadricDrawStyle (GLUquadric* quad, GLenum draw);
-GLAPI void GLAPIENTRY gluQuadricNormals (GLUquadric* quad, GLenum normal);
-GLAPI void GLAPIENTRY gluQuadricOrientation (GLUquadric* quad, GLenum orientation);
-GLAPI void GLAPIENTRY gluQuadricTexture (GLUquadric* quad, GLboolean texture);
-GLAPI GLint GLAPIENTRY gluScaleImage (GLenum format, GLsizei wIn, GLsizei hIn, GLenum typeIn, const void *dataIn, GLsizei wOut, GLsizei hOut, GLenum typeOut, GLvoid* dataOut);
-GLAPI void GLAPIENTRY gluSphere (GLUquadric* quad, GLdouble radius, GLint slices, GLint stacks);
-GLAPI void GLAPIENTRY gluTessBeginContour (GLUtesselator* tess);
-GLAPI void GLAPIENTRY gluTessBeginPolygon (GLUtesselator* tess, GLvoid* data);
-GLAPI void GLAPIENTRY gluTessCallback (GLUtesselator* tess, GLenum which, _GLUfuncptr CallBackFunc);
-GLAPI void GLAPIENTRY gluTessEndContour (GLUtesselator* tess);
-GLAPI void GLAPIENTRY gluTessEndPolygon (GLUtesselator* tess);
-GLAPI void GLAPIENTRY gluTessNormal (GLUtesselator* tess, GLdouble valueX, GLdouble valueY, GLdouble valueZ);
-GLAPI void GLAPIENTRY gluTessProperty (GLUtesselator* tess, GLenum which, GLdouble data);
-GLAPI void GLAPIENTRY gluTessVertex (GLUtesselator* tess, GLdouble *location, GLvoid* data);
-GLAPI GLint GLAPIENTRY gluUnProject (GLdouble winX, GLdouble winY, GLdouble winZ, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble* objX, GLdouble* objY, GLdouble* objZ);
-GLAPI GLint GLAPIENTRY gluUnProject4 (GLdouble winX, GLdouble winY, GLdouble winZ, GLdouble clipW, const GLdouble *model, const GLdouble *proj, const GLint *view, GLdouble nearVal, GLdouble farVal, GLdouble* objX, GLdouble* objY, GLdouble* objZ, GLdouble* objW);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __glu_h__ */
+++ /dev/null
-/*
- * Mesa 3-D graphics library
- * Version: 3.0
- * Copyright (C) 1995-1998 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.
- */
-
-
-#ifndef GLU_MANGLE_H
-#define GLU_MANGLE_H
-
-
-#define gluLookAt mgluLookAt
-#define gluOrtho2D mgluOrtho2D
-#define gluPerspective mgluPerspective
-#define gluPickMatrix mgluPickMatrix
-#define gluProject mgluProject
-#define gluUnProject mgluUnProject
-#define gluErrorString mgluErrorString
-#define gluScaleImage mgluScaleImage
-#define gluBuild1DMipmaps mgluBuild1DMipmaps
-#define gluBuild2DMipmaps mgluBuild2DMipmaps
-#define gluNewQuadric mgluNewQuadric
-#define gluDeleteQuadric mgluDeleteQuadric
-#define gluQuadricDrawStyle mgluQuadricDrawStyle
-#define gluQuadricOrientation mgluQuadricOrientation
-#define gluQuadricNormals mgluQuadricNormals
-#define gluQuadricTexture mgluQuadricTexture
-#define gluQuadricCallback mgluQuadricCallback
-#define gluCylinder mgluCylinder
-#define gluSphere mgluSphere
-#define gluDisk mgluDisk
-#define gluPartialDisk mgluPartialDisk
-#define gluNewNurbsRenderer mgluNewNurbsRenderer
-#define gluDeleteNurbsRenderer mgluDeleteNurbsRenderer
-#define gluLoadSamplingMatrices mgluLoadSamplingMatrices
-#define gluNurbsProperty mgluNurbsProperty
-#define gluGetNurbsProperty mgluGetNurbsProperty
-#define gluBeginCurve mgluBeginCurve
-#define gluEndCurve mgluEndCurve
-#define gluNurbsCurve mgluNurbsCurve
-#define gluBeginSurface mgluBeginSurface
-#define gluEndSurface mgluEndSurface
-#define gluNurbsSurface mgluNurbsSurface
-#define gluBeginTrim mgluBeginTrim
-#define gluEndTrim mgluEndTrim
-#define gluPwlCurve mgluPwlCurve
-#define gluNurbsCallback mgluNurbsCallback
-#define gluNewTess mgluNewTess
-#define gluDeleteTess mgluDeleteTess
-#define gluTessBeginPolygon mgluTessBeginPolygon
-#define gluTessBeginContour mgluTessBeginContour
-#define gluTessVertex mgluTessVertex
-#define gluTessEndPolygon mgluTessEndPolygon
-#define gluTessEndContour mgluTessEndContour
-#define gluTessProperty mgluTessProperty
-#define gluTessNormal mgluTessNormal
-#define gluTessCallback mgluTessCallback
-#define gluGetTessProperty mgluGetTessProperty
-#define gluBeginPolygon mgluBeginPolygon
-#define gluNextContour mgluNextContour
-#define gluEndPolygon mgluEndPolygon
-#define gluGetString mgluGetString
-#define gluBuild1DMipmapLevels mgluBuild1DMipmapLevels
-#define gluBuild2DMipmapLevels mgluBuild2DMipmapLevels
-#define gluBuild3DMipmapLevels mgluBuild3DMipmapLevels
-#define gluBuild3DMipmaps mgluBuild3DMipmaps
-#define gluCheckExtension mgluCheckExtension
-#define gluUnProject4 mgluUnProject4
-#define gluNurbsCallbackData mgluNurbsCallbackData
-#define gluNurbsCallbackDataEXT mgluNurbsCallbackDataEXT
-
-#endif
SConscript('glx/SConscript')
if env['platform'] not in ['darwin', 'haiku', 'sunos']:
SConscript('egl/main/SConscript')
- if env['platform'] not in ['darwin']:
- SConscript('glu/sgi/SConscript')
if env['gles']:
SConscript('mapi/shared-glapi/SConscript')
+++ /dev/null
-# src/glu/Makefile
-
-TOP = ../..
-
-include $(TOP)/configs/current
-
-
-SUBDIRS = sgi
-
-
-default: $(TOP)/configs/current
- @for dir in $(SUBDIRS) ; do \
- (cd $$dir && $(MAKE)) || exit 1 ; \
- done
-
-# GLU pkg-config file
-pcedit = sed \
- -e 's,@INSTALL_DIR@,$(INSTALL_DIR),' \
- -e 's,@INSTALL_LIB_DIR@,$(INSTALL_LIB_DIR),' \
- -e 's,@INSTALL_INC_DIR@,$(INSTALL_INC_DIR),' \
- -e 's,@VERSION@,$(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY),' \
- -e 's,@GLU_PC_REQ@,$(GLU_PC_REQ),' \
- -e 's,@GLU_PC_REQ_PRIV@,$(GLU_PC_REQ_PRIV),' \
- -e 's,@GLU_PC_LIB_PRIV@,$(GLU_PC_LIB_PRIV),' \
- -e 's,@GLU_PC_CFLAGS@,$(GLU_PC_CFLAGS),' \
- -e 's,@GLU_LIB@,$(GLU_LIB),'
-glu.pc: glu.pc.in
- $(pcedit) $< > $@
-
-install: glu.pc
- $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)
- $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig
- $(MINSTALL) $(TOP)/$(LIB_DIR)/$(GLU_LIB_GLOB) $(DESTDIR)$(INSTALL_LIB_DIR)
- $(INSTALL) -m 644 glu.pc $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig
-
-clean:
- -@for dir in $(SUBDIRS) ; do \
- (cd $$dir && $(MAKE) clean) ; \
- done
- -rm -f *.pc
+++ /dev/null
-prefix=@INSTALL_DIR@
-exec_prefix=${prefix}
-libdir=@INSTALL_LIB_DIR@
-includedir=@INSTALL_INC_DIR@
-
-Name: glu
-Description: Mesa OpenGL Utility library
-Requires: @GLU_PC_REQ@
-Requires.private: @GLU_PC_REQ_PRIV@
-Version: @VERSION@
-Libs: -L${libdir} -l@GLU_LIB@
-Libs.private: @GLU_PC_LIB_PRIV@
-Cflags: -I${includedir} @GLU_PC_CFLAGS@
+++ /dev/null
-# src/glu/sgi/Makefile
-
-.SUFFIXES : .cc
-
-TOP = ../../..
-
-include $(TOP)/configs/current
-
-GLU_MAJOR = 1
-GLU_MINOR = 3
-GLU_TINY = 0$(MESA_MAJOR)$(MESA_MINOR)0$(MESA_TINY)
-
-INCDIRS = -I$(TOP)/include -Iinclude -Iinternals -Ilibnurbs/internals -Ilibnurbs/interface -Ilibnurbs/nurbtess
-
-C_SOURCES = \
- libutil/error.c \
- libutil/glue.c \
- libutil/mipmap.c \
- libutil/project.c \
- libutil/quad.c \
- libutil/registry.c \
- libtess/dict.c \
- libtess/geom.c \
- libtess/memalloc.c \
- libtess/mesh.c \
- libtess/normal.c \
- libtess/priorityq.c \
- libtess/render.c \
- libtess/sweep.c \
- libtess/tess.c \
- libtess/tessmono.c
-
-CC_SOURCES = \
- libnurbs/interface/bezierEval.cc \
- libnurbs/interface/bezierPatch.cc \
- libnurbs/interface/bezierPatchMesh.cc \
- libnurbs/interface/glcurveval.cc \
- libnurbs/interface/glinterface.cc \
- libnurbs/interface/glrenderer.cc \
- libnurbs/interface/glsurfeval.cc \
- libnurbs/interface/incurveeval.cc \
- libnurbs/interface/insurfeval.cc \
- libnurbs/internals/arc.cc \
- libnurbs/internals/arcsorter.cc \
- libnurbs/internals/arctess.cc \
- libnurbs/internals/backend.cc \
- libnurbs/internals/basiccrveval.cc \
- libnurbs/internals/basicsurfeval.cc \
- libnurbs/internals/bin.cc \
- libnurbs/internals/bufpool.cc \
- libnurbs/internals/cachingeval.cc \
- libnurbs/internals/ccw.cc \
- libnurbs/internals/coveandtiler.cc \
- libnurbs/internals/curve.cc \
- libnurbs/internals/curvelist.cc \
- libnurbs/internals/curvesub.cc \
- libnurbs/internals/dataTransform.cc \
- libnurbs/internals/displaylist.cc \
- libnurbs/internals/flist.cc \
- libnurbs/internals/flistsorter.cc \
- libnurbs/internals/hull.cc \
- libnurbs/internals/intersect.cc \
- libnurbs/internals/knotvector.cc \
- libnurbs/internals/mapdesc.cc \
- libnurbs/internals/mapdescv.cc \
- libnurbs/internals/maplist.cc \
- libnurbs/internals/mesher.cc \
- libnurbs/internals/monoTriangulationBackend.cc \
- libnurbs/internals/monotonizer.cc \
- libnurbs/internals/mycode.cc \
- libnurbs/internals/nurbsinterfac.cc \
- libnurbs/internals/nurbstess.cc \
- libnurbs/internals/patch.cc \
- libnurbs/internals/patchlist.cc \
- libnurbs/internals/quilt.cc \
- libnurbs/internals/reader.cc \
- libnurbs/internals/renderhints.cc \
- libnurbs/internals/slicer.cc \
- libnurbs/internals/sorter.cc \
- libnurbs/internals/splitarcs.cc \
- libnurbs/internals/subdivider.cc \
- libnurbs/internals/tobezier.cc \
- libnurbs/internals/trimline.cc \
- libnurbs/internals/trimregion.cc \
- libnurbs/internals/trimvertpool.cc \
- libnurbs/internals/uarray.cc \
- libnurbs/internals/varray.cc \
- libnurbs/nurbtess/directedLine.cc \
- libnurbs/nurbtess/gridWrap.cc \
- libnurbs/nurbtess/monoChain.cc \
- libnurbs/nurbtess/monoPolyPart.cc \
- libnurbs/nurbtess/monoTriangulation.cc \
- libnurbs/nurbtess/partitionX.cc \
- libnurbs/nurbtess/partitionY.cc \
- libnurbs/nurbtess/polyDBG.cc \
- libnurbs/nurbtess/polyUtil.cc \
- libnurbs/nurbtess/primitiveStream.cc \
- libnurbs/nurbtess/quicksort.cc \
- libnurbs/nurbtess/rectBlock.cc \
- libnurbs/nurbtess/sampleComp.cc \
- libnurbs/nurbtess/sampleCompBot.cc \
- libnurbs/nurbtess/sampleCompRight.cc \
- libnurbs/nurbtess/sampleCompTop.cc \
- libnurbs/nurbtess/sampleMonoPoly.cc \
- libnurbs/nurbtess/sampledLine.cc \
- libnurbs/nurbtess/searchTree.cc
-
-SOURCES = $(C_SOURCES) $(CC_SOURCES)
-
-C_OBJECTS = $(C_SOURCES:.c=.o)
-CC_OBJECTS = $(CC_SOURCES:.cc=.o)
-OBJECTS = $(C_OBJECTS) $(CC_OBJECTS)
-
-
-##### RULES #####
-
-.c.o:
- $(CC) -c $(INCDIRS) $(CFLAGS) -DNDEBUG -DLIBRARYBUILD $< -o $@
-
-.cc.o:
- $(CXX) -c $(INCDIRS) $(CXXFLAGS) -DNDEBUG -DLIBRARYBUILD $< -o $@
-
-
-##### TARGETS #####
-
-default:
- $(MAKE) $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME)
-
-$(TOP)/$(LIB_DIR):
- -mkdir $(TOP)/$(LIB_DIR)
-
-# Make the library:
-$(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME): $(OBJECTS)
- $(MKLIB) -o $(GLU_LIB) -linker '$(CXX)' -ldflags '$(LDFLAGS)' \
- -major $(GLU_MAJOR) -minor $(GLU_MINOR) -patch $(GLU_TINY) \
- -cplusplus $(MKLIB_OPTIONS) -install $(TOP)/$(LIB_DIR) \
- -exports glu.exports -id $(INSTALL_LIB_DIR)/lib$(GLU_LIB).$(GLU_MAJOR).dylib \
- $(GLU_LIB_DEPS) $(OBJECTS)
-
-
-clean:
- -rm -f *.o */*.o */*/*.o
- -rm -f *.lo */*.lo */*/*.lo
- -rm -f *.la */*.la */*/*.la
+++ /dev/null
-Import('*')
-
-env = env.Clone()
-
-env.Prepend(CPPPATH = [
- 'include',
- 'internals',
- 'libnurbs/internals',
- 'libnurbs/interface',
- 'libnurbs/nurbtess',
-])
-
-env.Prepend(CPPDEFINES = [
- 'LIBRARYBUILD',
- 'RESOLVE_3D_TEXTURE_SUPPORT',
-])
-
-sources = [
- 'libutil/error.c',
- 'libutil/glue.c',
- 'libutil/mipmap.c',
- 'libutil/project.c',
- 'libutil/quad.c',
- 'libutil/registry.c',
- 'libtess/dict.c',
- 'libtess/geom.c',
- 'libtess/memalloc.c',
- 'libtess/mesh.c',
- 'libtess/normal.c',
- 'libtess/priorityq.c',
- 'libtess/render.c',
- 'libtess/sweep.c',
- 'libtess/tess.c',
- 'libtess/tessmono.c',
- 'libnurbs/interface/bezierEval.cc',
- 'libnurbs/interface/bezierPatch.cc',
- 'libnurbs/interface/bezierPatchMesh.cc',
- 'libnurbs/interface/glcurveval.cc',
- 'libnurbs/interface/glinterface.cc',
- 'libnurbs/interface/glrenderer.cc',
- 'libnurbs/interface/glsurfeval.cc',
- 'libnurbs/interface/incurveeval.cc',
- 'libnurbs/interface/insurfeval.cc',
- 'libnurbs/internals/arc.cc',
- 'libnurbs/internals/arcsorter.cc',
- 'libnurbs/internals/arctess.cc',
- 'libnurbs/internals/backend.cc',
- 'libnurbs/internals/basiccrveval.cc',
- 'libnurbs/internals/basicsurfeval.cc',
- 'libnurbs/internals/bin.cc',
- 'libnurbs/internals/bufpool.cc',
- 'libnurbs/internals/cachingeval.cc',
- 'libnurbs/internals/ccw.cc',
- 'libnurbs/internals/coveandtiler.cc',
- 'libnurbs/internals/curve.cc',
- 'libnurbs/internals/curvelist.cc',
- 'libnurbs/internals/curvesub.cc',
- 'libnurbs/internals/dataTransform.cc',
- 'libnurbs/internals/displaylist.cc',
- 'libnurbs/internals/flist.cc',
- 'libnurbs/internals/flistsorter.cc',
- 'libnurbs/internals/hull.cc',
- 'libnurbs/internals/intersect.cc',
- 'libnurbs/internals/knotvector.cc',
- 'libnurbs/internals/mapdesc.cc',
- 'libnurbs/internals/mapdescv.cc',
- 'libnurbs/internals/maplist.cc',
- 'libnurbs/internals/mesher.cc',
- 'libnurbs/internals/monoTriangulationBackend.cc',
- 'libnurbs/internals/monotonizer.cc',
- 'libnurbs/internals/mycode.cc',
- 'libnurbs/internals/nurbsinterfac.cc',
- 'libnurbs/internals/nurbstess.cc',
- 'libnurbs/internals/patch.cc',
- 'libnurbs/internals/patchlist.cc',
- 'libnurbs/internals/quilt.cc',
- 'libnurbs/internals/reader.cc',
- 'libnurbs/internals/renderhints.cc',
- 'libnurbs/internals/slicer.cc',
- 'libnurbs/internals/sorter.cc',
- 'libnurbs/internals/splitarcs.cc',
- 'libnurbs/internals/subdivider.cc',
- 'libnurbs/internals/tobezier.cc',
- 'libnurbs/internals/trimline.cc',
- 'libnurbs/internals/trimregion.cc',
- 'libnurbs/internals/trimvertpool.cc',
- 'libnurbs/internals/uarray.cc',
- 'libnurbs/internals/varray.cc',
- 'libnurbs/nurbtess/directedLine.cc',
- 'libnurbs/nurbtess/gridWrap.cc',
- 'libnurbs/nurbtess/monoChain.cc',
- 'libnurbs/nurbtess/monoPolyPart.cc',
- 'libnurbs/nurbtess/monoTriangulation.cc',
- 'libnurbs/nurbtess/partitionX.cc',
- 'libnurbs/nurbtess/partitionY.cc',
- 'libnurbs/nurbtess/polyDBG.cc',
- 'libnurbs/nurbtess/polyUtil.cc',
- 'libnurbs/nurbtess/primitiveStream.cc',
- 'libnurbs/nurbtess/quicksort.cc',
- 'libnurbs/nurbtess/rectBlock.cc',
- 'libnurbs/nurbtess/sampleComp.cc',
- 'libnurbs/nurbtess/sampleCompBot.cc',
- 'libnurbs/nurbtess/sampleCompRight.cc',
- 'libnurbs/nurbtess/sampleCompTop.cc',
- 'libnurbs/nurbtess/sampleMonoPoly.cc',
- 'libnurbs/nurbtess/sampledLine.cc',
- 'libnurbs/nurbtess/searchTree.cc',
-]
-
-if env['platform'] == 'windows':
- # -D_OPENGL32_ -Iinclude -DBUILD_GL32
- env.PrependUnique(LIBS = [
- 'gdi32',
- 'user32',
- 'opengl32',
- ])
- target = 'glu32'
- sources += ['glu.def']
-else:
- env.PrependUnique(LIBS = [
- 'GL',
- ])
- target = 'glu'
-
-if env['platform'] == 'haiku':
- glu = env.StaticLibrary(
- target = target,
- source = sources
- )
-else:
- glu = env.SharedLibrary(
- target = target,
- source = sources
- )
- env.Alias('glu', env.InstallSharedLibrary(glu, version=(1, 3, 0)))
-
-
-if env['platform'] == 'windows':
- glu = env.FindIxes(glu, 'LIBPREFIX', 'LIBSUFFIX')
-else:
- glu = env.FindIxes(glu, 'SHLIBPREFIX', 'SHLIBSUFFIX')
-
-Export('glu')
+++ /dev/null
-/*
- * This file contains nothing. It's just there so there's at least a single
- * source file for libGLU.la in this directory.
- */
+++ /dev/null
-;DESCRIPTION 'Mesa GLU (OpenGL work-alike) for Win32'
-VERSION 5.1
-;
-; Module definition file for GLU (GLU32.DLL)
-;
-; Note: The GLU functions use the STDCALL
-; function calling convention. Microsoft's
-; GLU32 uses this convention and so must the
-; Mesa GLU32 so that the Mesa DLL can be used
-; as a drop-in replacement.
-;
-; The linker exports STDCALL entry points with
-; 'decorated' names; e.g., _glBegin@0, where the
-; trailing number is the number of bytes of
-; parameter data pushed onto the stack. The
-; callee is responsible for popping this data
-; off the stack, usually via a RETF n instruction.
-;
-; However, the Microsoft GLU32.DLL does not export
-; the decorated names, even though the calling convention
-; is STDCALL. So, this module definition file is
-; needed to force the Mesa GLU32.DLL to export the
-; symbols in the same manner as the Microsoft DLL.
-; Were it not for this problem, this file would not
-; be needed (for the glu* functions) since the entry
-; points are compiled with dllexport declspec.
-;
-
-EXPORTS
- gluBeginCurve
- gluBeginPolygon
- gluBeginSurface
- gluBeginTrim
- gluBuild1DMipmapLevels
- gluBuild1DMipmaps
- gluBuild2DMipmapLevels
- gluBuild2DMipmaps
- gluBuild3DMipmapLevels
- gluBuild3DMipmaps
- gluCheckExtension
- gluCylinder
- gluDeleteNurbsRenderer
- gluDeleteQuadric
- gluDeleteTess
- gluDisk
- gluEndCurve
- gluEndPolygon
- gluEndSurface
- gluEndTrim
- gluErrorString
- gluGetNurbsProperty
- gluGetString
- gluGetTessProperty
- gluLoadSamplingMatrices
- gluLookAt
- gluNewNurbsRenderer
- gluNewQuadric
- gluNewTess
- gluNextContour
- gluNurbsCallback
- gluNurbsCallbackData
- gluNurbsCallbackDataEXT
- gluNurbsCurve
- gluNurbsProperty
- gluNurbsSurface
- gluOrtho2D
- gluPartialDisk
- gluPerspective
- gluPickMatrix
- gluProject
- gluPwlCurve
- gluQuadricCallback
- gluQuadricDrawStyle
- gluQuadricNormals
- gluQuadricOrientation
- gluQuadricTexture
- gluScaleImage
- gluSphere
- gluTessBeginContour
- gluTessBeginPolygon
- gluTessCallback
- gluTessEndContour
- gluTessEndPolygon
- gluTessNormal
- gluTessProperty
- gluTessVertex
- gluUnProject
- gluUnProject4
+++ /dev/null
- gluBeginCurve
- gluBeginPolygon
- gluBeginSurface
- gluBeginTrim
- gluBuild1DMipmapLevels
- gluBuild1DMipmaps
- gluBuild2DMipmapLevels
- gluBuild2DMipmaps
- gluBuild3DMipmapLevels
- gluBuild3DMipmaps
- gluCheckExtension
- gluCylinder
- gluDeleteNurbsRenderer
- gluDeleteQuadric
- gluDeleteTess
- gluDisk
- gluEndCurve
- gluEndPolygon
- gluEndSurface
- gluEndTrim
- gluErrorString
- gluGetNurbsProperty
- gluGetString
- gluGetTessProperty
- gluLoadSamplingMatrices
- gluLookAt
- gluNewNurbsRenderer
- gluNewQuadric
- gluNewTess
- gluNextContour
- gluNurbsCallback
- gluNurbsCallbackData
- gluNurbsCallbackDataEXT
- gluNurbsCurve
- gluNurbsProperty
- gluNurbsSurface
- gluOrtho2D
- gluPartialDisk
- gluPerspective
- gluPickMatrix
- gluProject
- gluPwlCurve
- gluQuadricCallback
- gluQuadricDrawStyle
- gluQuadricNormals
- gluQuadricOrientation
- gluQuadricTexture
- gluScaleImage
- gluSphere
- gluTessBeginContour
- gluTessBeginPolygon
- gluTessCallback
- gluTessEndContour
- gluTessEndPolygon
- gluTessNormal
- gluTessProperty
- gluTessVertex
- gluUnProject
- gluUnProject4
- mgluBeginCurve
- mgluBeginPolygon
- mgluBeginSurface
- mgluBeginTrim
- mgluBuild1DMipmapLevels
- mgluBuild1DMipmaps
- mgluBuild2DMipmapLevels
- mgluBuild2DMipmaps
- mgluBuild3DMipmapLevels
- mgluBuild3DMipmaps
- mgluCheckExtension
- mgluCylinder
- mgluDeleteNurbsRenderer
- mgluDeleteQuadric
- mgluDeleteTess
- mgluDisk
- mgluEndCurve
- mgluEndPolygon
- mgluEndSurface
- mgluEndTrim
- mgluErrorString
- mgluGetNurbsProperty
- mgluGetString
- mgluGetTessProperty
- mgluLoadSamplingMatrices
- mgluLookAt
- mgluNewNurbsRenderer
- mgluNewQuadric
- mgluNewTess
- mgluNextContour
- mgluNurbsCallback
- mgluNurbsCallbackData
- mgluNurbsCallbackDataEXT
- mgluNurbsCurve
- mgluNurbsProperty
- mgluNurbsSurface
- mgluOrtho2D
- mgluPartialDisk
- mgluPerspective
- mgluPickMatrix
- mgluProject
- mgluPwlCurve
- mgluQuadricCallback
- mgluQuadricDrawStyle
- mgluQuadricNormals
- mgluQuadricOrientation
- mgluQuadricTexture
- mgluScaleImage
- mgluSphere
- mgluTessBeginContour
- mgluTessBeginPolygon
- mgluTessCallback
- mgluTessEndContour
- mgluTessEndPolygon
- mgluTessNormal
- mgluTessProperty
- mgluTessVertex
- mgluUnProject
- mgluUnProject4
+++ /dev/null
-_*gluBeginCurve
-_*gluBeginPolygon
-_*gluBeginSurface
-_*gluBeginTrim
-_*gluBuild1DMipmapLevels
-_*gluBuild1DMipmaps
-_*gluBuild2DMipmapLevels
-_*gluBuild2DMipmaps
-_*gluBuild3DMipmapLevels
-_*gluBuild3DMipmaps
-_*gluCheckExtension
-_*gluCylinder
-_*gluDeleteNurbsRenderer
-_*gluDeleteQuadric
-_*gluDeleteTess
-_*gluDisk
-_*gluEndCurve
-_*gluEndPolygon
-_*gluEndSurface
-_*gluEndTrim
-_*gluErrorString
-_*gluGetNurbsProperty
-_*gluGetString
-_*gluGetTessProperty
-_*gluLoadSamplingMatrices
-_*gluLookAt
-_*gluNewNurbsRenderer
-_*gluNewQuadric
-_*gluNewTess
-_*gluNextContour
-_*gluNurbsCallback
-_*gluNurbsCallbackData
-_*gluNurbsCallbackDataEXT
-_*gluNurbsCurve
-_*gluNurbsProperty
-_*gluNurbsSurface
-_*gluOrtho2D
-_*gluPartialDisk
-_*gluPerspective
-_*gluPickMatrix
-_*gluProject
-_*gluPwlCurve
-_*gluQuadricCallback
-_*gluQuadricDrawStyle
-_*gluQuadricNormals
-_*gluQuadricOrientation
-_*gluQuadricTexture
-_*gluScaleImage
-_*gluSphere
-_*gluTessBeginContour
-_*gluTessBeginPolygon
-_*gluTessCallback
-_*gluTessEndContour
-_*gluTessEndPolygon
-_*gluTessNormal
-_*gluTessProperty
-_*gluTessVertex
-_*gluUnProject
-_*gluUnProject4
+++ /dev/null
-/*
-** gluos.h - operating system dependencies for GLU
-**
-*/
-#ifdef __VMS
-#ifdef __cplusplus
-#pragma message disable nocordel
-#pragma message disable codeunreachable
-#pragma message disable codcauunr
-#endif
-#endif
-
-#ifdef __WATCOMC__
-/* Disable *lots* of warnings to get a clean build. I can't be bothered fixing the
- * code at the moment, as it is pretty ugly.
- */
-#pragma warning 7 10
-#pragma warning 13 10
-#pragma warning 14 10
-#pragma warning 367 10
-#pragma warning 379 10
-#pragma warning 726 10
-#pragma warning 836 10
-#endif
-
-#ifdef BUILD_FOR_SNAP
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <malloc.h>
-
-#elif defined(_WIN32)
-
-#include <stdlib.h> /* For _MAX_PATH definition */
-#include <stdio.h>
-#include <malloc.h>
-
-#define WIN32_LEAN_AND_MEAN
-#define NOGDI
-#define NOIME
-#define NOMINMAX
-
-#ifdef __MINGW64_VERSION_MAJOR
- #undef _WIN32_WINNT
-#endif
-
-#ifndef _WIN32_WINNT
- /* XXX: Workaround a bug in mingw-w64's headers when NOGDI is set and
- * _WIN32_WINNT >= 0x0600 */
- #define _WIN32_WINNT 0x0400
-#endif
-#ifndef STRICT
- #define STRICT 1
-#endif
-
-#include <windows.h>
-
-/* Disable warnings */
-#if defined(_MSC_VER)
-#pragma warning(disable : 4101)
-#pragma warning(disable : 4244)
-#pragma warning(disable : 4761)
-#endif
-
-#if defined(_MSC_VER) && _MSC_VER >= 1200 && _MSC_VER < 1300
-#pragma comment(linker, "/OPT:NOWIN98")
-#endif
-
-#ifndef WINGDIAPI
-#define WINGDIAPI
-#endif
-
-#elif defined(__OS2__)
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <malloc.h>
-#define WINGDIAPI
-
-#else
-
-/* Disable Microsoft-specific keywords */
-#define GLAPIENTRY
-#define WINGDIAPI
-
-#endif
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-#include <math.h>
-#include "bezierEval.h"
-
-#ifdef __WATCOMC__
-#pragma warning 14 10
-#endif
-
-#define TOLERANCE 0.0001
-
-#ifndef MAX_ORDER
-#define MAX_ORDER 16
-#endif
-
-#ifndef MAX_DIMENSION
-#define MAX_DIMENSION 4
-#endif
-
-static void normalize(float vec[3]);
-static void crossProduct(float x[3], float y[3], float ret[3]);
-#if 0 // UNUSED
-static void bezierCurveEvalfast(float u0, float u1, int order, float *ctlpoints, int stride, int dimension, float u, float retpoint[]);
-#endif
-
-static float binomialCoefficients[8][8] = {
- {1,0,0,0,0,0,0,0},
- {1,1,0,0,0,0,0,0},
- {1,2,1,0,0,0,0,0},
- {1,3,3,1,0,0,0,0},
- {1,4,6,4,1,0,0,0},
- {1,5,10,10,5,1,0,0},
- {1,6,15,20,15,6,1,0},
- {1,7,21,35,35,21,7,1}
-};
-
-void bezierCurveEval(float u0, float u1, int order, float *ctlpoints, int stride, int dimension, float u, float retpoint[])
-{
- float uprime = (u-u0)/(u1-u0);
- float *ctlptr = ctlpoints;
- float oneMinusX = 1.0f-uprime;
- float XPower = 1.0f;
-
- int i,k;
- for(k=0; k<dimension; k++)
- retpoint[k] = (*(ctlptr + k));
-
- for(i=1; i<order; i++){
- ctlptr += stride;
- XPower *= uprime;
- for(k=0; k<dimension; k++) {
- retpoint[k] = retpoint[k]*oneMinusX + ctlptr[k]* binomialCoefficients[order-1][i] * XPower;
- }
- }
-}
-
-
-#if 0 // UNUSED
-/*order = degree +1 >=1.
- */
-void bezierCurveEvalfast(float u0, float u1, int order, float *ctlpoints, int stride, int dimension, float u, float retpoint[])
-{
- float uprime = (u-u0)/(u1-u0);
- float buf[MAX_ORDER][MAX_ORDER][MAX_DIMENSION];
- float* ctlptr = ctlpoints;
- int r, i,j;
- for(i=0; i<order; i++) {
- for(j=0; j<dimension; j++)
- buf[0][i][j] = ctlptr[j];
- ctlptr += stride;
- }
- for(r=1; r<order; r++){
- for(i=0; i<order-r; i++) {
- for(j=0; j<dimension; j++)
- buf[r][i][j] = (1-uprime)*buf[r-1][i][j] + uprime*buf[r-1][i+1][j];
- }
- }
-
- for(j=0; j<dimension; j++)
- retpoint[j] = buf[order-1][0][j];
-}
-#endif
-
-
-/*order = degree +1 >=1.
- */
-void bezierCurveEvalDer(float u0, float u1, int order, float *ctlpoints, int stride, int dimension, float u, float retDer[])
-{
- int i,k;
- float width = u1-u0;
- float *ctlptr = ctlpoints;
-
- float buf[MAX_ORDER][MAX_DIMENSION];
- if(order == 1){
- for(k=0; k<dimension; k++)
- retDer[k]=0;
- }
- for(i=0; i<order-1; i++){
- for(k=0; k<dimension; k++) {
- buf[i][k] = (ctlptr[stride+k] - ctlptr[k])*(order-1)/width;
- }
- ctlptr += stride;
- }
-
- bezierCurveEval(u0, u1, order-1, (float*) buf, MAX_DIMENSION, dimension, u, retDer);
-}
-
-void bezierCurveEvalDerGen(int der, float u0, float u1, int order, float *ctlpoints, int stride, int dimension, float u, float retDer[])
-{
- int i,k,r;
- float *ctlptr = ctlpoints;
- float width=u1-u0;
- float buf[MAX_ORDER][MAX_ORDER][MAX_DIMENSION];
- if(der<0) der=0;
- for(i=0; i<order; i++){
- for(k=0; k<dimension; k++){
- buf[0][i][k] = ctlptr[k];
- }
- ctlptr += stride;
- }
-
-
- for(r=1; r<=der; r++){
- for(i=0; i<order-r; i++){
- for(k=0; k<dimension; k++){
- buf[r][i][k] = (buf[r-1][i+1][k] - buf[r-1][i][k])*(order-r)/width;
- }
- }
- }
-
- bezierCurveEval(u0, u1, order-der, (float *) (buf[der]), MAX_DIMENSION, dimension, u, retDer);
-}
-
-/*the Bezier bivarite polynomial is:
- * sum[i:0,uorder-1][j:0,vorder-1] { ctlpoints[i*ustride+j*vstride] * B(i)*B(j)
- * where B(i) and B(j) are basis functions
- */
-void bezierSurfEvalDerGen(int uder, int vder, float u0, float u1, int uorder, float v0, float v1, int vorder, int dimension, float *ctlpoints, int ustride, int vstride, float u, float v, float ret[])
-{
- int i;
- float newPoints[MAX_ORDER][MAX_DIMENSION];
-
- for(i=0; i<uorder; i++){
-
- bezierCurveEvalDerGen(vder, v0, v1, vorder, ctlpoints+ustride*i, vstride, dimension, v, newPoints[i]);
-
- }
-
- bezierCurveEvalDerGen(uder, u0, u1, uorder, (float *) newPoints, MAX_DIMENSION, dimension, u, ret);
-}
-
-
-/*division by w is performed*/
-void bezierSurfEval(float u0, float u1, int uorder, float v0, float v1, int vorder, int dimension, float *ctlpoints, int ustride, int vstride, float u, float v, float ret[])
-{
- bezierSurfEvalDerGen(0, 0, u0, u1, uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u, v, ret);
- if(dimension == 4) /*homogeneous*/{
- ret[0] /= ret[3];
- ret[1] /= ret[3];
- ret[2] /= ret[3];
- }
-}
-
-void bezierSurfEvalNormal(float u0, float u1, int uorder, float v0, float v1, int vorder, int dimension, float *ctlpoints, int ustride, int vstride, float u, float v, float retNormal[])
-{
- float partialU[4];
- float partialV[4];
- assert(dimension>=3 && dimension <=4);
- bezierSurfEvalDerGen(1,0, u0, u1, uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u, v, partialU);
- bezierSurfEvalDerGen(0,1, u0, u1, uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u, v, partialV);
-
- if(dimension == 3){/*inhomogeneous*/
- crossProduct(partialU, partialV, retNormal);
-
- normalize(retNormal);
-
- return;
- }
- else { /*homogeneous*/
- float val[4]; /*the point coordinates (without derivative)*/
- float newPartialU[MAX_DIMENSION];
- float newPartialV[MAX_DIMENSION];
- int i;
- bezierSurfEvalDerGen(0,0, u0, u1, uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u, v, val);
-
- for(i=0; i<=2; i++){
- newPartialU[i] = partialU[i] * val[3] - val[i] * partialU[3];
- newPartialV[i] = partialV[i] * val[3] - val[i] * partialV[3];
- }
- crossProduct(newPartialU, newPartialV, retNormal);
- normalize(retNormal);
- }
-}
-
-/*if size is 0, then nothing is done*/
-static void normalize(float vec[3])
-{
- float size = (float)sqrt(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
-
- if(size < TOLERANCE)
- {
-#ifdef DEBUG
- fprintf(stderr, "Warning: in oglBSpline.c normal is 0\n");
-#endif
- return;
- }
- else {
- vec[0] = vec[0]/size;
- vec[1] = vec[1]/size;
- vec[2] = vec[2]/size;
- }
-}
-
-
-static void crossProduct(float x[3], float y[3], float ret[3])
-{
- ret[0] = x[1]*y[2] - y[1]*x[2];
- ret[1] = x[2]*y[0] - y[2]*x[0];
- ret[2] = x[0]*y[1] - y[0]*x[1];
-
-}
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-#ifndef _BEZIEREVAL_H
-#define _BEZIEREVAL_H
-
-void bezierCurveEval(float u0, float u1, int order, float *ctlpoints, int stride, int dimension, float u, float retpoint[]);
-void bezierCurveEvalDer(float u0, float u1, int order, float *ctlpoints, int stride, int dimension, float u, float retDer[]);
-void bezierCurveEvalDerGen(int der, float u0, float u1, int order, float *ctlpoints, int stride, int dimension, float u, float retDer[]);
-
-
-void bezierSurfEvalDerGen(int uder, int vder, float u0, float u1, int uorder, float v0, float v1, int vorder, int dimension, float *ctlpoints, int ustride, int vstride, float u, float v, float ret[]);
-
-void bezierSurfEval(float u0, float u1, int uorder, float v0, float v1, int vorder, int dimension, float *ctlpoints, int ustride, int vstride, float u, float v, float ret[]);
-
-void bezierSurfEvalNormal(float u0, float u1, int uorder, float v0, float v1, int vorder, int dimension, float *ctlpoints, int ustride, int vstride, float u, float v, float retNormal[]);
-
-
-#endif
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include "gluos.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-#include <GL/glu.h> /*for drawing bzier patch*/
-#include "bezierPatch.h"
-#include "bezierEval.h"
-
-/*
- *allocate an instance of bezierPatch. The control points are unknown. But
- *the space of this array is allocated with size of
- * uorder*vorder*dimension
- *
- */
-bezierPatch* bezierPatchMake(float umin, float vmin, float umax, float vmax, int uorder, int vorder, int dimension)
-{
- bezierPatch* ret = (bezierPatch*) malloc(sizeof(bezierPatch));
- assert(ret);
- ret->umin = umin;
- ret->vmin = vmin;
- ret->umax = umax;
- ret->vmax = vmax;
- ret->uorder = uorder;
- ret->vorder = vorder;
- ret->dimension = dimension;
- ret->ctlpoints = (float*) malloc(sizeof(float) * dimension * uorder * vorder);
- assert(ret->ctlpoints);
-
- ret->next = NULL;
-
- return ret;
-}
-
-bezierPatch* bezierPatchMake2(float umin, float vmin, float umax, float vmax, int uorder, int vorder, int dimension, int ustride, int vstride, float* ctlpoints)
-{
- bezierPatch* ret = (bezierPatch*) malloc(sizeof(bezierPatch));
- assert(ret);
- ret->umin = umin;
- ret->vmin = vmin;
- ret->umax = umax;
- ret->vmax = vmax;
- ret->uorder = uorder;
- ret->vorder = vorder;
- ret->dimension = dimension;
- ret->ctlpoints = (float*) malloc(sizeof(float) * dimension * uorder * vorder);
- assert(ret->ctlpoints);
-
- /*copy the control points there*/
- int the_ustride = vorder * dimension;
- int the_vstride = dimension;
- for(int i=0; i<uorder; i++)
- for(int j=0; j<vorder; j++)
- for(int k=0; k<dimension; k++)
- ret->ctlpoints[i * the_ustride + j*the_vstride+k] = ctlpoints[i*ustride+j*vstride+k];
-
- ret->next = NULL;
-
- return ret;
-}
-
-/*
- *deallocate the space as allocated by Make
- */
-void bezierPatchDelete(bezierPatch *b)
-{
- free(b->ctlpoints);
- free(b);
-}
-
-/*delete the whole linked list
- */
-void bezierPatchDeleteList(bezierPatch *b)
-{
- bezierPatch *temp;
- while (b != NULL) {
- temp = b;
- b = b->next;
- bezierPatchDelete(temp);
- }
-}
-
-bezierPatch* bezierPatchInsert(bezierPatch *list, bezierPatch *b)
-{
- b->next = list;
- return b;
-}
-
-/*print the data stored in this patch*/
-void bezierPatchPrint(bezierPatch *b)
-{
- printf("bezierPatch:\n");
- printf("umin,umax=(%f,%f), (vmin, vmax)=(%f,%f)\n", b->umin, b->umax, b->vmin, b->vmax);
- printf("uorder=%i, vorder=%i\n", b->uorder, b->vorder);
- printf("idmension = %i\n", b->dimension);
-}
-
-/*print the whole list*/
-void bezierPatchPrintList(bezierPatch *list)
-{
- bezierPatch* temp;
- for(temp=list; temp != NULL; temp = temp->next)
- bezierPatchPrint(temp);
-}
-
-void bezierPatchEval(bezierPatch *b, float u, float v, float ret[])
-{
- if( u >= b->umin && u<= b->umax
- && v >= b->vmin && v<= b->vmax)
- {
-
- bezierSurfEval(b->umin, b->umax, b->uorder, b->vmin, b->vmax, b->vorder, b->dimension, b->ctlpoints, b->dimension * b->vorder, b->dimension, u, v, ret);
-
- }
- else if(b->next != NULL)
- bezierPatchEval(b->next, u,v, ret);
- else
- bezierSurfEval(b->umin, b->umax, b->uorder, b->vmin, b->vmax, b->vorder, b->dimension, b->ctlpoints, b->dimension * b->vorder, b->dimension, u, v, ret);
-}
-
-/*the returned normal is normlized
- */
-void bezierPatchEvalNormal(bezierPatch *b, float u, float v, float ret[])
-{
- bezierSurfEvalNormal(b->umin, b->umax, b->uorder, b->vmin, b->vmax, b->vorder, b->dimension, b->ctlpoints, b->dimension * b->vorder, b->dimension, u, v, ret);
-
- if( u >= b->umin && u<= b->umax
- && v >= b->vmin && v<= b->vmax)
- {
- bezierSurfEvalNormal(b->umin, b->umax, b->uorder, b->vmin, b->vmax, b->vorder, b->dimension, b->ctlpoints, b->dimension * b->vorder, b->dimension, u, v, ret);
- }
- else if(b->next != NULL)
- bezierPatchEvalNormal(b->next, u,v, ret);
- else
- bezierSurfEvalNormal(b->umin, b->umax, b->uorder, b->vmin, b->vmax, b->vorder, b->dimension, b->ctlpoints, b->dimension * b->vorder, b->dimension, u, v, ret);
-
-}
-
-void bezierPatchDraw(bezierPatch *bpatch, int u_reso, int v_reso)
-{
- if(bpatch->dimension == 3)
- glMap2f(GL_MAP2_VERTEX_3, bpatch->umin, bpatch->umax, 3*bpatch->vorder, bpatch->uorder, bpatch->vmin, bpatch->vmax,3, bpatch->vorder, (GLfloat*) bpatch->ctlpoints);
- else
- glMap2f(GL_MAP2_VERTEX_4, bpatch->umin, bpatch->umax, 4*bpatch->vorder, bpatch->uorder, bpatch->vmin, bpatch->vmax,3, bpatch->vorder, (GLfloat*) bpatch->ctlpoints);
-
- glMapGrid2f(u_reso, bpatch->umin, bpatch->umax,
- v_reso, bpatch->vmin, bpatch->vmax);
- glEvalMesh2(GL_LINE, 0, u_reso, 0, v_reso);
-}
-
-void bezierPatchListDraw(bezierPatch *list, int u_reso, int v_reso)
-{
- bezierPatch *temp;
-glEnable(GL_LIGHTING);
-glEnable(GL_LIGHT0);
-glEnable(GL_MAP2_VERTEX_3);
-glEnable(GL_AUTO_NORMAL);
-glEnable(GL_NORMALIZE);
-glColor3f(1,0,0);
-#ifdef DEBUG
-printf("mapmap\n");
-#endif
-
-
- for(temp = list; temp != NULL; temp = temp->next)
- bezierPatchDraw(temp, u_reso, v_reso);
-}
-
-
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-#ifndef _BEZIERPATCH_H
-#define _BEZIERPATCH_H
-
-typedef struct bezierPatch{
- float umin, vmin, umax, vmax;
- int uorder; /*order= degree + 1*/
- int vorder;
-
- /*
- *the control points are stored in a one dimensional array.
- *the surface is defined as:
- * s(u,v) = sum_{i,j} P(i,j) * B_i(u) * B_j(v).
- *where P(i,j) are the control points, B_i(.) are Bezier
- *basis functions.
- *Each control point can have dimension 3 or 4: (x,y,z,w).
- *The components of P(i,j) are stored in a one dimensional
- *array:
- * ctlpoints[]
- *in the order of:
- * P[0,0], P[0,1], ..., P[0,vorder-1],
- * P[1,0], P[1,1], ..., P[1,vorder-1],
- * ...
- * P[uorder-1,0], P[uorder-1,1], ..., P[uorder-1,vorder-1].
- */
- int dimension;
- float* ctlpoints;
-
- /*
- *in case we have to manage multiple bezierPatches.
- */
- struct bezierPatch *next;
-
-} bezierPatch;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-bezierPatch* bezierPatchMake(float umin, float vmin, float umax, float vmax, int urder, int vorder, int dimension);
-
-bezierPatch* bezierPatchMake2(float umin, float vmin, float umax, float vmax, int urder, int vorder, int dimension, int ustride, int vstride, float *ctlpoints);
-
-
-bezierPatch* bezierPatchInsert(bezierPatch *list, bezierPatch *b);
-
-void bezierPatchDelete(bezierPatch *b);
-
-void bezierPatchDeleteList(bezierPatch *b);
-
-void bezierPatchPrint(bezierPatch *b);
-
-void bezierPatchPrintList(bezierPatch *list);
-
-void bezierPatchEval(bezierPatch *b, float u, float v, float ret[]);
-
-void bezierPatchEvalNormal(bezierPatch *b, float u, float v, float retNormal[]);
-
-void bezierPatchEval(bezierPatch *b, float u, float v, float ret[]);
-
-void bezierPatchEvalNormal(bezierPatch *b, float u, float v, float ret[]);
-
-
-void bezierPatchDraw(bezierPatch *bpatch, int u_reso, int v_reso);
-
-void bezierPatchListDraw(bezierPatch *list, int u_reso, int v_reso);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include "gluos.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-#include <GL/gl.h>
-#include "bezierEval.h"
-#include "bezierPatchMesh.h"
-
-static int isDegenerate(float A[2], float B[2], float C[2]);
-
-void drawStrips(float *vertex_array, float *normal_array, int *length_array, GLenum *type_array, int num_strips)
-{
- int i,j,k;
- k=0;
- /*k is the index of the first component of the current vertex*/
- for(i=0; i<num_strips; i++)
- {
- glBegin(type_array[i]);
- for(j=0; j<length_array[i]; j++)
- {
- glNormal3fv(normal_array+k);
- glVertex3fv(vertex_array+k);
- k += 3;
- }
- glEnd();
- }
-}
-
-void bezierPatchMeshListDelDeg(bezierPatchMesh* list)
-{
- bezierPatchMesh* temp;
- for(temp=list; temp != NULL; temp = temp->next)
- {
- bezierPatchMeshDelDeg(temp);
- }
-}
-
-void bezierPatchMeshListDelete(bezierPatchMesh *list)
-{
- if(list == NULL) return;
- bezierPatchMeshListDelete(list->next);
- bezierPatchMeshDelete(list);
-}
-
-
-
-
-bezierPatchMesh* bezierPatchMeshListReverse(bezierPatchMesh* list)
-{
- bezierPatchMesh* ret=NULL;
- bezierPatchMesh* temp;
- bezierPatchMesh* nextone;
- for(temp = list; temp != NULL; temp = nextone)
- {
- nextone = temp->next;
- ret=bezierPatchMeshListInsert(ret, temp);
- }
- return ret;
-}
-
-/*maptype is either GL_MAP2_VERTEX_3 or GL_MAP2_VERTEX_4
- */
-bezierPatchMesh *bezierPatchMeshMake(int maptype, float umin, float umax, int ustride, int uorder, float vmin, float vmax, int vstride, int vorder, float *ctlpoints, int size_UVarray, int size_length_array)
-{
- int i,j,k;
- int dimension;
- int the_ustride;
- int the_vstride;
-
- if(maptype == GL_MAP2_VERTEX_3) dimension = 3;
- else if (maptype==GL_MAP2_VERTEX_4) dimension = 4;
- else {
- fprintf(stderr, "error in inMap2f, maptype=%i is wrong, maptype,map is invalid\n", maptype);
- return NULL;
- }
-
- bezierPatchMesh *ret = (bezierPatchMesh*) malloc(sizeof(bezierPatchMesh));
- assert(ret);
-
- ret->bpatch_normal = NULL;
- ret->bpatch_color = NULL;
- ret->bpatch_texcoord = NULL;
- ret->bpatch = bezierPatchMake(umin, vmin, umax, vmax, uorder, vorder, dimension);
-
- /*copy the control points there*/
- the_ustride = vorder * dimension;
- the_vstride = dimension;
- for(i=0; i<uorder; i++)
- for(j=0; j<vorder; j++)
- for(k=0; k<dimension; k++)
- ret->bpatch->ctlpoints[i * the_ustride + j*the_vstride+k] = ctlpoints[i*ustride+j*vstride+k];
-
-
- ret->size_UVarray = size_UVarray;
- ret->size_length_array = size_length_array;
- ret->UVarray = (float*) malloc(sizeof(float) * size_UVarray);
- assert(ret->UVarray);
- ret->length_array = (int *)malloc(sizeof(int) * size_length_array);
- assert(ret->length_array);
- ret->type_array = (GLenum *)malloc(sizeof(GLenum) * size_length_array);
- assert(ret->type_array);
-
- ret->index_UVarray = 0;
- ret->index_length_array = 0;
-
- ret->vertex_array = NULL;
- ret->normal_array = NULL;
- ret->color_array = NULL;
- ret->texcoord_array = NULL;
-
- ret->next = NULL;
- return ret;
-}
-
-bezierPatchMesh *bezierPatchMeshMake2(int size_UVarray, int size_length_array)
-{
- bezierPatchMesh *ret = (bezierPatchMesh*) malloc(sizeof(bezierPatchMesh));
- assert(ret);
-
- ret->bpatch = NULL;
- ret->bpatch_normal = NULL;
- ret->bpatch_color = NULL;
- ret->bpatch_texcoord = NULL;
-
- ret->size_UVarray = size_UVarray;
- ret->size_length_array = size_length_array;
- ret->UVarray = (float*) malloc(sizeof(float) * size_UVarray);
- assert(ret->UVarray);
- ret->length_array = (int *)malloc(sizeof(int) * size_length_array);
- assert(ret->length_array);
- ret->type_array = (GLenum *)malloc(sizeof(GLenum) * size_length_array);
- assert(ret->type_array);
-
- ret->index_UVarray = 0;
- ret->index_length_array = 0;
-
- ret->vertex_array = NULL;
- ret->normal_array = NULL;
- ret->color_array = NULL;
- ret->texcoord_array = NULL;
-
- ret->next = NULL;
- return ret;
-}
-
-void bezierPatchMeshPutPatch(bezierPatchMesh *bpm, int maptype, float umin, float umax, int ustride, int uorder, float vmin, float vmax, int vstride, int vorder, float *ctlpoints)
-{
- switch(maptype){
- case GL_MAP2_VERTEX_3:
- bpm->bpatch = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 3, ustride, vstride, ctlpoints);
- break;
- case GL_MAP2_VERTEX_4:
- bpm->bpatch = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 4,ustride, vstride, ctlpoints );
- break;
- case GL_MAP2_NORMAL:
- bpm->bpatch_normal = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 3, ustride, vstride, ctlpoints);
- break;
- case GL_MAP2_INDEX:
- bpm->bpatch_color = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 1, ustride, vstride, ctlpoints);
- break;
- case GL_MAP2_COLOR_4:
- bpm->bpatch_color = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 4, ustride, vstride, ctlpoints);
- break;
- case GL_MAP2_TEXTURE_COORD_1:
- bpm->bpatch_texcoord = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 1, ustride, vstride, ctlpoints);
- break;
- case GL_MAP2_TEXTURE_COORD_2:
- bpm->bpatch_texcoord = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 2, ustride, vstride, ctlpoints);
- break;
- case GL_MAP2_TEXTURE_COORD_3:
- bpm->bpatch_texcoord = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 3, ustride, vstride, ctlpoints);
- break;
- case GL_MAP2_TEXTURE_COORD_4:
- bpm->bpatch_texcoord = bezierPatchMake2(umin, vmin, umax, vmax, uorder, vorder, 4, ustride, vstride, ctlpoints);
- break;
- default:
- fprintf(stderr, "error in bezierPatchMeshPutPatch, maptype=%i is wrong, maptype,map is invalid\n", maptype);
- }
-}
-
-
-/*delete everything including the arrays. So if you want to output the
- *pointers of the arrays, you should not use this function to deallocate space.
- *you should dealocate manually
- */
-void bezierPatchMeshDelete(bezierPatchMesh *bpm)
-{
- if(bpm->bpatch != NULL)
- bezierPatchDelete(bpm->bpatch);
- if(bpm->bpatch_normal != NULL)
- bezierPatchDelete(bpm->bpatch_normal);
- if(bpm->bpatch_color != NULL)
- bezierPatchDelete(bpm->bpatch_color);
- if(bpm->bpatch_texcoord != NULL)
- bezierPatchDelete(bpm->bpatch_texcoord);
-
- free(bpm->UVarray);
- free(bpm->length_array);
- free(bpm->vertex_array);
- free(bpm->normal_array);
- free(bpm->type_array);
- free(bpm);
-}
-
-/*begin a strip
- *type is the primitive type:
- */
-void bezierPatchMeshBeginStrip(bezierPatchMesh *bpm, GLenum type)
-{
- bpm->counter = 0;
- bpm->type = type;
-}
-
-/*signal the end of the current strip*/
-void bezierPatchMeshEndStrip(bezierPatchMesh *bpm)
-{
- int i;
-
- /*if there are no vertices in this strip, then nothing needs to be done*/
- if(bpm->counter == 0) return;
-
- /*if the length_array is full, it should be expanded*/
- if(bpm->index_length_array >= bpm->size_length_array)
- {
- int *temp = (int*) malloc(sizeof(int) * (bpm->size_length_array*2 + 1));
- assert(temp);
- GLenum *temp_type = (GLenum*) malloc(sizeof(GLenum) * (bpm->size_length_array*2 + 1));
- assert(temp_type);
- /*update the size*/
- bpm->size_length_array = bpm->size_length_array*2 + 1;
-
- /*copy*/
- for(i=0; i<bpm->index_length_array; i++)
- {
- temp[i] = bpm->length_array[i];
- temp_type[i] = bpm->type_array[i];
- }
-
- /*deallocate old array*/
- free(bpm->length_array);
- free(bpm->type_array);
-
- /*point to the new array which is twice as bigger*/
- bpm->length_array = temp;
- bpm->type_array = temp_type;
- }
- bpm->type_array[bpm->index_length_array] = bpm->type;
- bpm->length_array[bpm->index_length_array++] = bpm->counter;
-
-}
-
-/*insert (u,v) */
-void bezierPatchMeshInsertUV(bezierPatchMesh *bpm, float u, float v)
-{
- int i;
- /*if the UVarray is full, it should be expanded*/
- if(bpm->index_UVarray+1 >= bpm->size_UVarray)
- {
- float *temp = (float*) malloc(sizeof(float) * (bpm->size_UVarray * 2 + 2));
- assert(temp);
-
- /*update the size*/
- bpm->size_UVarray = bpm->size_UVarray*2 + 2;
-
- /*copy*/
- for(i=0; i<bpm->index_UVarray; i++)
- {
- temp[i] = bpm->UVarray[i];
- }
-
- /*deallocate old array*/
- free(bpm->UVarray);
-
- /*pointing to the new arrays*/
- bpm->UVarray = temp;
- }
- /*insert the new UV*/
- bpm->UVarray[bpm->index_UVarray] = u;
- bpm->index_UVarray++;
- bpm->UVarray[bpm->index_UVarray] = v;
- bpm->index_UVarray++;
-
- /*update counter: one more vertex*/
- bpm->counter++;
-
-
-}
-
-void bezierPatchMeshPrint(bezierPatchMesh *bpm)
-{
- int i;
- printf("the bezier patch is\n");
- bezierPatchPrint(bpm->bpatch);
- printf("index_length_array= %i\n", bpm->index_length_array);
- printf("size_length_array =%i\n", bpm->size_length_array);
- printf("index_UVarray =%i\n", bpm->index_UVarray);
- printf("size_UVarray =%i\n", bpm->size_UVarray);
- printf("UVarray is\n");
- for(i=0; i<bpm->index_UVarray; i++)
- printf("%f ", bpm->UVarray[i]);
-
- printf("length_array is\n");
- for(i=0; i<bpm->index_length_array; i++)
- printf("%i ", bpm->length_array[i]);
- printf("\n");
-
-}
-
-/*insert a new patch in front of the current linked list and return the new list*/
-bezierPatchMesh* bezierPatchMeshListInsert(bezierPatchMesh* list, bezierPatchMesh* bpm)
-{
- bpm->next=list;
- return bpm;
-}
-
-/*print all the patches*/
-void bezierPatchMeshListPrint(bezierPatchMesh* list)
-{
- bezierPatchMesh *temp;
- for(temp = list; temp != NULL; temp = temp->next)
- {
- bezierPatchMeshPrint(temp);
- }
-}
-
-int bezierPatchMeshListTotalStrips(bezierPatchMesh* list)
-{
- int sum=0;
- bezierPatchMesh *temp;
- for(temp=list; temp != NULL; temp = temp->next)
- {
- sum += temp->index_length_array;
- }
- return sum;
-}
-
-int bezierPatchMeshListTotalVert(bezierPatchMesh* list)
-{
- int sum=0;
- bezierPatchMesh *temp;
- for(temp=list; temp != NULL; temp = temp->next)
- {
- sum += temp->index_UVarray;
- }
- return sum/2;
-}
-
-int bezierPatchMeshListNumTriangles(bezierPatchMesh* list)
-{
- int sum=0;
- bezierPatchMesh* temp;
- for(temp=list; temp != NULL; temp = temp->next)
- {
- sum += bezierPatchMeshNumTriangles(temp);
- }
- return sum;
-}
-
-int bezierPatchMeshNumTriangles(bezierPatchMesh* bpm)
-{
- int i;
- int sum=0;
- for(i=0; i<bpm->index_length_array; i++)
- {
- switch(bpm->type_array[i])
- {
- case GL_TRIANGLES:
- sum += bpm->length_array[i]/3;
- break;
- case GL_TRIANGLE_FAN:
- if(bpm->length_array[i] > 2)
- sum += bpm->length_array[i]-2;
- break;
- case GL_TRIANGLE_STRIP:
- if(bpm->length_array[i] > 2)
- sum += bpm->length_array[i]-2;
- break;
- case GL_QUAD_STRIP:
- if(bpm->length_array[i]>2)
- sum += (bpm->length_array[i]-2);
- break;
- default:
- fprintf(stderr,"error in bezierPatchMeshListNumTriangles, type invalid\n");
- }
- }
- return sum;
-}
-
-/*delete degenerate triangles*/
-void bezierPatchMeshDelDeg(bezierPatchMesh* bpm)
-{
- if(bpm == NULL) return;
- int i,j,k;
- int *new_length_array;
- GLenum *new_type_array;
- int index_new_length_array;
- float *new_UVarray;
- int index_new_UVarray;
-
- new_length_array = (int*)malloc(sizeof(int) * bpm->index_length_array);
- assert(new_length_array);
- new_type_array = (GLenum*)malloc(sizeof(GLenum) * bpm->index_length_array);
- assert(new_length_array);
- new_UVarray = (float*) malloc(sizeof(float) * bpm->index_UVarray);
- assert(new_UVarray);
-
- index_new_length_array = 0;
- index_new_UVarray=0;
- k=0;
- for(i=0; i<bpm->index_length_array; i++){
-
- /*(if not degenerate, we have to copy*/
- if( (bpm->length_array[i] != 3) || (!isDegenerate(bpm->UVarray+k, bpm->UVarray+k+2, bpm->UVarray+k+4)))
- {
- for(j=0; j<2* bpm->length_array[i]; j++)
- new_UVarray[index_new_UVarray++] = bpm->UVarray[k++];
-
- new_length_array[index_new_length_array] = bpm->length_array[i];
- new_type_array[index_new_length_array] = bpm->type_array[i];
- index_new_length_array++;
- }
- else
- {
- k += 6;
- }
- }
- free(bpm->UVarray);
- free(bpm->length_array);
- free(bpm->type_array);
- bpm->UVarray=new_UVarray;
- bpm->length_array=new_length_array;
- bpm->type_array=new_type_array;
- bpm->index_UVarray = index_new_UVarray;
- bpm->index_length_array = index_new_length_array;
-
-}
-
-/*(u,v) to XYZ
- *the xyz and normals are stored in vertex_array,
- *and normal_array. the spaces of both are allocated here
- */
-void bezierPatchMeshEval(bezierPatchMesh* bpm)
-{
- int i,j,k,l;
- float u,v;
- float u0 = bpm->bpatch->umin;
- float u1 = bpm->bpatch->umax;
- int uorder = bpm->bpatch->uorder;
- float v0 = bpm->bpatch->vmin;
- float v1 = bpm->bpatch->vmax;
- int vorder = bpm->bpatch->vorder;
- int dimension = bpm->bpatch->dimension;
- int ustride = dimension * vorder;
- int vstride = dimension;
- float *ctlpoints = bpm->bpatch->ctlpoints;
-
- bpm->vertex_array = (float*) malloc(sizeof(float)* (bpm->index_UVarray/2) * 3);
- assert(bpm->vertex_array);
- bpm->normal_array = (float*) malloc(sizeof(float)* (bpm->index_UVarray/2) * 3);
- assert(bpm->normal_array);
-
- k=0;
- l=0;
- for(i=0; i<bpm->index_length_array; i++)
- {
- for(j=0; j<bpm->length_array[i]; j++)
- {
- u = bpm->UVarray[k];
- v = bpm->UVarray[k+1];
- bezierSurfEval(u0,u1,uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u,v, bpm->vertex_array+l);
- bezierSurfEvalNormal(u0,u1,uorder, v0, v1, vorder, dimension, ctlpoints, ustride, vstride, u,v, bpm->normal_array+l);
- k += 2;
- l += 3;
- }
- }
-}
-
-void bezierPatchMeshListEval(bezierPatchMesh* list)
-{
- bezierPatchMesh* temp;
- for(temp = list; temp != NULL; temp = temp->next)
- {
- bezierPatchMeshEval(temp);
- }
-}
-
-void bezierPatchMeshDraw(bezierPatchMesh* bpm)
-{
- int i,j,k;
- k=0;
- /*k is the index of the first component of the current vertex*/
- for(i=0; i<bpm->index_length_array; i++)
- {
- glBegin(bpm->type_array[i]);
- for(j=0; j<bpm->length_array[i]; j++)
- {
- glNormal3fv(bpm->normal_array+k);
- glVertex3fv(bpm->vertex_array+k);
- k+= 3;
- }
- glEnd();
- }
-}
-
-void bezierPatchMeshListDraw(bezierPatchMesh* list)
-{
- bezierPatchMesh* temp;
- for(temp = list; temp != NULL; temp = temp->next)
- {
- bezierPatchMeshDraw(temp);
- }
-}
-
-void bezierPatchMeshListCollect(bezierPatchMesh* list, float **vertex_array, float **normal_array, int **length_array, GLenum **type_array, int *num_strips)
-{
- int i,j,k,l;
- bezierPatchMesh *temp;
- int total_num_vertices = bezierPatchMeshListTotalVert(list);
- (*vertex_array) = (float *) malloc(sizeof(float) * total_num_vertices*3);
- assert(*vertex_array);
- (*normal_array) = (float *) malloc(sizeof(float) * total_num_vertices*3);
- assert(*normal_array);
-
- *num_strips = bezierPatchMeshListTotalStrips(list);
-
- *length_array = (int*) malloc(sizeof(int) * (*num_strips));
- assert(*length_array);
-
- *type_array = (GLenum*) malloc(sizeof(GLenum) * (*num_strips));
- assert(*type_array);
-
- k=0;
- l=0;
- for(temp = list; temp != NULL; temp = temp->next)
- {
- int x=0;
- for(i=0; i<temp->index_length_array; i++)
- {
- for(j=0; j<temp->length_array[i]; j++)
- {
- (*vertex_array)[k] = temp->vertex_array[x];
- (*vertex_array)[k+1] = temp->vertex_array[x+1];
- (*vertex_array)[k+2] = temp->vertex_array[x+2];
-
- (*normal_array)[k] = temp->normal_array[x];
- (*normal_array)[k+1] = temp->normal_array[x+1];
- (*normal_array)[k+2] = temp->normal_array[x+2];
-
- x += 3;
- k += 3;
- }
- (*type_array)[l] = temp->type_array[i];
- (*length_array)[l++] = temp->length_array[i];
- }
- }
-}
-
-
-
-static int isDegenerate(float A[2], float B[2], float C[2])
-{
- if( (A[0] == B[0] && A[1]==B[1]) ||
- (A[0] == C[0] && A[1]==C[1]) ||
- (B[0] == C[0] && B[1]==C[1])
- )
- return 1;
- else
- return 0;
-}
-
-
-
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-#ifndef _BEZIERPATCHMESH_H
-#define _BEZIERPATCHMESH_H
-
-#include <GL/gl.h>
-#include "bezierPatch.h"
-
-typedef struct bezierPatchMesh{
- bezierPatch *bpatch; /*vertex*/
- bezierPatch *bpatch_normal;
- bezierPatch *bpatch_texcoord; /*s,t,r,q*/
- bezierPatch *bpatch_color; /*RGBA*/
-
- float *UVarray; /*all UV components of all vertices of all strips*/
- int *length_array; /*[i] is the number of vertices in the ith strip*/
- GLenum *type_array; /*[i] is the type of the ith primitive*/
-
- /*to support dynamic insertion*/
- int size_UVarray;
- int index_UVarray;
- int size_length_array;
- int index_length_array;
-
- int counter; /*track the current strip size*/
- GLenum type; /*track the current type: 0: GL_TRIANGLES, 1: GL_TRIANGLE_STRIP*/
-
- /*we eventually want to evaluate from (u,v) to (x,y,z) and draw them*/
- float *vertex_array; /*each vertex contains three components*/
- float *normal_array; /*each normal contains three components*/
- float *color_array;
- float *texcoord_array;
-
- /*in case we need a linked list*/
- struct bezierPatchMesh *next;
-} bezierPatchMesh;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-
-bezierPatchMesh *bezierPatchMeshMake(int maptype, float umin, float umax, int ustride, int uorder, float vmin, float vmax, int vstride, int vorder, float *ctlpoints, int size_UVarray, int size_length_array);
-
-/*initilize patches to be null*/
-bezierPatchMesh *bezierPatchMeshMake2(int size_UVarray, int size_length_array);
-
-void bezierPatchMeshPutPatch(bezierPatchMesh *bpm, int maptype, float umin, float umax, int ustride, int uorder, float vmin, float vmax, int vstride, int vorder, float *ctlpoints);
-
-void bezierPatchMeshDelete(bezierPatchMesh *bpm);
-
-void bezierPatchMeshBeginStrip(bezierPatchMesh *bpm, GLenum type);
-
-void bezierPatchMeshEndStrip(bezierPatchMesh *bpm);
-
-void bezierPatchMeshInsertUV(bezierPatchMesh *bpm, float u, float v);
-
-void bezierPatchMeshPrint(bezierPatchMesh *bpm);
-
-bezierPatchMesh* bezierPatchMeshListInsert(bezierPatchMesh* list, bezierPatchMesh* bpm);
-
-void bezierPatchMeshListPrint(bezierPatchMesh* list);
-
-int bezierPatchMeshListTotalStrips(bezierPatchMesh* list);
-
-int bezierPatchMeshListTotalVert(bezierPatchMesh* list);
-int bezierPatchMeshNumTriangles(bezierPatchMesh* bpm);
-int bezierPatchMeshListNumTriangles(bezierPatchMesh* list);
-
-void bezierPatchMeshDelDeg(bezierPatchMesh* bpm);
-
-
-void bezierPatchMeshEval(bezierPatchMesh* bpm);
-
-void bezierPatchMeshDraw(bezierPatchMesh* bpm);
-
-void bezierPatchMeshListDraw(bezierPatchMesh* list);
-void bezierPatchMeshListEval(bezierPatchMesh* list);
-void bezierPatchMeshListCollect(bezierPatchMesh* list, float **vertex_array, float **normal_array, int **length_array, GLenum **type_array, int *num_strips);
-
-void bezierPatchMeshListDelDeg(bezierPatchMesh* list);
-void bezierPatchMeshListDelete(bezierPatchMesh *list);
-bezierPatchMesh* bezierPatchMeshListReverse(bezierPatchMesh* list);
-void drawStrips(float *vertex_array, float *normal_array, int *length_array, GLenum *type_array, int num_strips);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * glcurveval.c++
- *
- */
-
-/* Polynomial Evaluator Interface */
-
-#include "gluos.h"
-#include "glimports.h"
-#include "glrenderer.h"
-#include "glcurveval.h"
-#include "nurbsconsts.h"
-
-OpenGLCurveEvaluator::OpenGLCurveEvaluator(void)
-{
- //no default callback functions
- beginCallBackN = NULL;
- endCallBackN = NULL;
- vertexCallBackN = NULL;
- normalCallBackN = NULL;
- colorCallBackN = NULL;
- texcoordCallBackN = NULL;
- beginCallBackData = NULL;
- endCallBackData = NULL;
- vertexCallBackData = NULL;
- normalCallBackData = NULL;
- colorCallBackData = NULL;
- texcoordCallBackData = NULL;
-
- userData = NULL;
-
- vertex_flag = 0;
- normal_flag = 0;
- color_flag = 0;
- texcoord_flag = 0;
-
- em_vertex.uprime = -1.0;
- em_normal.uprime = -1.0;
- em_color.uprime = -1.0;
- em_texcoord.uprime = -1.0;
- output_triangles = 0; // don't output triangles by default
-}
-
-OpenGLCurveEvaluator::~OpenGLCurveEvaluator(void)
-{
-}
-
-/* added nonsense to avoid the warning messages at compile time */
-void
-OpenGLCurveEvaluator::addMap(CurveMap *m)
-{
- m = m;
-}
-
-void
-OpenGLCurveEvaluator::range1f(long type, REAL *from, REAL *to)
-{
- type = type;
- from = from;
- to = to;
-}
-
-void
-OpenGLCurveEvaluator::domain1f(REAL ulo, REAL uhi)
-{
- ulo = ulo;
- uhi = uhi;
-}
-
-void
-OpenGLCurveEvaluator::bgnline(void)
-{
- if(output_triangles)
- beginCallBack(GL_LINE_STRIP, userData);
- else
- glBegin((GLenum) GL_LINE_STRIP);
-}
-
-void
-OpenGLCurveEvaluator::endline(void)
-{
- if(output_triangles)
- endCallBack(userData);
- else
- glEnd();
-}
-
-/*---------------------------------------------------------------------------
- * disable - turn off a curve map
- *---------------------------------------------------------------------------
- */
-void
-OpenGLCurveEvaluator::disable(long type)
-{
- glDisable((GLenum) type);
-}
-
-/*---------------------------------------------------------------------------
- * enable - turn on a curve map
- *---------------------------------------------------------------------------
- */
-void
-OpenGLCurveEvaluator::enable(long type)
-{
- glEnable((GLenum) type);
-}
-
-/*-------------------------------------------------------------------------
- * mapgrid1f - define a lattice of points with origin and offset
- *-------------------------------------------------------------------------
- */
-void
-OpenGLCurveEvaluator::mapgrid1f(long nu, REAL u0, REAL u1)
-{
- if(output_triangles)
- {
- global_grid_u0 = u0;
- global_grid_u1 = u1;
- global_grid_nu = (int) nu;
- }
- else
- glMapGrid1f((GLint) nu, (GLfloat) u0, (GLfloat) u1);
-}
-
-/*-------------------------------------------------------------------------
- * bgnmap1 - preamble to curve definition and evaluations
- *-------------------------------------------------------------------------
- */
-void
-OpenGLCurveEvaluator::bgnmap1f(long)
-{
- if(output_triangles)
- {
- //initialized so that no maps are set initially
- vertex_flag = 0;
- normal_flag = 0;
- color_flag = 0;
- texcoord_flag = 0;
- //no need to worry about gl states when doing callback
- }
- else
- glPushAttrib((GLbitfield) GL_EVAL_BIT);
-}
-
-/*-------------------------------------------------------------------------
- * endmap1 - postamble to a curve map
- *-------------------------------------------------------------------------
- */
-void
-OpenGLCurveEvaluator::endmap1f(void)
-{
- if(output_triangles)
- {
-
- }
- else
- glPopAttrib();
-}
-
-/*-------------------------------------------------------------------------
- * map1f - pass a desription of a curve map
- *-------------------------------------------------------------------------
- */
-void
-OpenGLCurveEvaluator::map1f(
- long type, /* map type */
- REAL ulo, /* lower parametric bound */
- REAL uhi, /* upper parametric bound */
- long stride, /* distance to next point in REALS */
- long order, /* parametric order */
- REAL *pts /* control points */
-)
-{
- if(output_triangles)
- {
- int dimension = 0;
- int which = 0;
- switch(type){
- case GL_MAP1_VERTEX_3:
- which = 0;
- dimension = 3;
- break;
- case GL_MAP1_VERTEX_4:
- which=0;
- dimension = 4;
- break;
- case GL_MAP1_INDEX:
- which=2;
- dimension = 1;
- break;
- case GL_MAP1_COLOR_4:
- which=2;
- dimension = 4;
- break;
- case GL_MAP1_NORMAL:
- which=1;
- dimension = 3;
- break;
- case GL_MAP1_TEXTURE_COORD_1:
- which=3;
- dimension = 1;
- break;
- case GL_MAP1_TEXTURE_COORD_2:
- which=3;
- dimension = 2;
- break;
-
- case GL_MAP1_TEXTURE_COORD_3:
- which=3;
- dimension = 3;
- break;
- case GL_MAP1_TEXTURE_COORD_4:
- which=3;
- dimension = 4;
- break;
- }
- inMap1f(which, dimension, ulo, uhi, stride, order, pts);
- }
- else
- glMap1f((GLenum) type, (GLfloat) ulo, (GLfloat) uhi, (GLint) stride,
- (GLint) order, (const GLfloat *) pts);
-}
-
-/*-------------------------------------------------------------------------
- * mapmesh1f - evaluate a mesh of points on lattice
- *-------------------------------------------------------------------------
- */
-void OpenGLCurveEvaluator::mapmesh1f(long style, long from, long to)
-{
- if(output_triangles)
- {
- inMapMesh1f((int) from, (int) to);
- }
- else
- {
- switch(style) {
- default:
- case N_MESHFILL:
- case N_MESHLINE:
- glEvalMesh1((GLenum) GL_LINE, (GLint) from, (GLint) to);
- break;
- case N_MESHPOINT:
- glEvalMesh1((GLenum) GL_POINT, (GLint) from, (GLint) to);
- break;
- }
- }
-}
-
-/*-------------------------------------------------------------------------
- * evalpoint1i - evaluate a point on a curve
- *-------------------------------------------------------------------------
- */
-void OpenGLCurveEvaluator::evalpoint1i(long i)
-{
- glEvalPoint1((GLint) i);
-}
-
-/*-------------------------------------------------------------------------
- * evalcoord1f - evaluate a point on a curve
- *-------------------------------------------------------------------------
- */
-void OpenGLCurveEvaluator::evalcoord1f(long, REAL u)
-{
- glEvalCoord1f((GLfloat) u);
-}
-
-void
-#ifdef _WIN32
-OpenGLCurveEvaluator::putCallBack(GLenum which, void (GLAPIENTRY *fn)())
-#else
-OpenGLCurveEvaluator::putCallBack(GLenum which, _GLUfuncptr fn)
-#endif
-{
- switch(which)
- {
- case GLU_NURBS_BEGIN:
- beginCallBackN = (void (GLAPIENTRY *) (GLenum)) fn;
- break;
- case GLU_NURBS_END:
- endCallBackN = (void (GLAPIENTRY *) (void)) fn;
- break;
- case GLU_NURBS_VERTEX:
- vertexCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn;
- break;
- case GLU_NURBS_NORMAL:
- normalCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn;
- break;
- case GLU_NURBS_COLOR:
- colorCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn;
- break;
- case GLU_NURBS_TEXTURE_COORD:
- texcoordCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn;
- break;
- case GLU_NURBS_BEGIN_DATA:
- beginCallBackData = (void (GLAPIENTRY *) (GLenum, void*)) fn;
- break;
- case GLU_NURBS_END_DATA:
- endCallBackData = (void (GLAPIENTRY *) (void*)) fn;
- break;
- case GLU_NURBS_VERTEX_DATA:
- vertexCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn;
- break;
- case GLU_NURBS_NORMAL_DATA:
- normalCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn;
- break;
- case GLU_NURBS_COLOR_DATA:
- colorCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn;
- break;
- case GLU_NURBS_TEXTURE_COORD_DATA:
- texcoordCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn;
- break;
- }
-}
-
-void
-OpenGLCurveEvaluator::beginCallBack(GLenum which, void *data)
-{
- if(beginCallBackData)
- beginCallBackData(which, data);
- else if(beginCallBackN)
- beginCallBackN(which);
-}
-
-void
-OpenGLCurveEvaluator::endCallBack(void *data)
-{
- if(endCallBackData)
- endCallBackData(data);
- else if(endCallBackN)
- endCallBackN();
-}
-
-void
-OpenGLCurveEvaluator::vertexCallBack(const GLfloat *vert, void* data)
-{
- if(vertexCallBackData)
- vertexCallBackData(vert, data);
- else if(vertexCallBackN)
- vertexCallBackN(vert);
-}
-
-
-void
-OpenGLCurveEvaluator::normalCallBack(const GLfloat *normal, void* data)
-{
- if(normalCallBackData)
- normalCallBackData(normal, data);
- else if(normalCallBackN)
- normalCallBackN(normal);
-}
-
-void
-OpenGLCurveEvaluator::colorCallBack(const GLfloat *color, void* data)
-{
- if(colorCallBackData)
- colorCallBackData(color, data);
- else if(colorCallBackN)
- colorCallBackN(color);
-}
-
-void
-OpenGLCurveEvaluator::texcoordCallBack(const GLfloat *texcoord, void* data)
-{
- if(texcoordCallBackData)
- texcoordCallBackData(texcoord, data);
- else if(texcoordCallBackN)
- texcoordCallBackN(texcoord);
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * glcurveval.h
- *
- */
-
-#ifndef __gluglcurveval_h_
-#define __gluglcurveval_h_
-
-#include "gluos.h"
-#include <GL/gl.h>
-#include <GL/glu.h>
-#include "basiccrveval.h"
-
-class CurveMap;
-
-/*for internal evaluator callback stuff*/
-#ifndef IN_MAX_BEZIER_ORDER
-#define IN_MAX_BEZIER_ORDER 40 /*XXX should be bigger than machine order*/
-#endif
-
-#ifndef IN_MAX_DIMENSION
-#define IN_MAX_DIMENSION 4
-#endif
-
-typedef struct curveEvalMachine{
- REAL uprime; //cached previously evaluated uprime
- int k; //the dimension
- REAL u1;
- REAL u2;
- int ustride;
- int uorder;
- REAL ctlpoints[IN_MAX_BEZIER_ORDER*IN_MAX_DIMENSION];
- REAL ucoeff[IN_MAX_BEZIER_ORDER];//cache the polynomial values
-} curveEvalMachine;
-
-class OpenGLCurveEvaluator : public BasicCurveEvaluator {
-public:
- OpenGLCurveEvaluator(void);
- virtual ~OpenGLCurveEvaluator(void);
- void range1f(long, REAL *, REAL *);
- void domain1f(REAL, REAL);
- void addMap(CurveMap *);
-
- void enable(long);
- void disable(long);
- void bgnmap1f(long);
- void map1f(long, REAL, REAL, long, long, REAL *);
- void mapgrid1f(long, REAL, REAL);
- void mapmesh1f(long, long, long);
- void evalpoint1i(long);
- void evalcoord1f(long, REAL);
- void endmap1f(void);
-
- void bgnline(void);
- void endline(void);
-
- void put_vertices_call_back(int flag)
- {
- output_triangles = flag;
- }
-#ifdef _WIN32
- void putCallBack(GLenum which, void (GLAPIENTRY *fn)() );
-#else
- void putCallBack(GLenum which, _GLUfuncptr fn );
-#endif
- void set_callback_userData(void *data)
- {
- userData = data;
- }
-
-/*------------------begin for curveEvalMachine------------*/
-curveEvalMachine em_vertex;
-curveEvalMachine em_normal;
-curveEvalMachine em_color;
-curveEvalMachine em_texcoord;
-int vertex_flag; //whether there is a vertex map or not
-int normal_flag; //whether there is a normal map or not
-int color_flag; //whether there is a color map or not
-int texcoord_flag; //whether there is a texture map or not
-
-REAL global_grid_u0;
-REAL global_grid_u1;
-int global_grid_nu;
-
-void inMap1f(int which, //0: vert, 1: norm, 2: color, 3: tex
- int dimension,
- REAL ulower,
- REAL uupper,
- int ustride,
- int uorder,
- REAL *ctlpoints);
-
-void inPreEvaluate(int order, REAL vprime, REAL *coeff);
-void inDoDomain1(curveEvalMachine *em, REAL u, REAL *retPoint);
-void inDoEvalCoord1(REAL u);
-void inMapMesh1f(int umin, int umax);
-
-void (GLAPIENTRY *beginCallBackN) (GLenum type);
-void (GLAPIENTRY *endCallBackN) (void);
-void (GLAPIENTRY *vertexCallBackN) (const GLfloat *vert);
-void (GLAPIENTRY *normalCallBackN) (const GLfloat *normal);
-void (GLAPIENTRY *colorCallBackN) (const GLfloat *color);
-void (GLAPIENTRY *texcoordCallBackN) (const GLfloat *texcoord);
-
-void (GLAPIENTRY *beginCallBackData) (GLenum type, void* data);
-void (GLAPIENTRY *endCallBackData) (void* data);
-void (GLAPIENTRY *vertexCallBackData) (const GLfloat *vert, void* data);
-void (GLAPIENTRY *normalCallBackData) (const GLfloat *normal, void* data);
-void (GLAPIENTRY *colorCallBackData) (const GLfloat *color, void* data);
-void (GLAPIENTRY *texcoordCallBackData) (const GLfloat *texcoord, void* data);
-
-void* userData; //the opaque pointer for Data callback functions
-void beginCallBack(GLenum type, void* data);
-void endCallBack(void* data);
-void vertexCallBack(const GLfloat *vert, void *data);
-void normalCallBack(const GLfloat *normal, void* data);
-void colorCallBack(const GLfloat *color, void* data);
-void texcoordCallBack(const GLfloat *texcoord, void* data);
-
-
-/*------------------end for curveEvalMachine------------*/
-
-private:
- int output_triangles; //true 1; false 0
-};
-
-#endif /* __gluglcurveval_h_ */
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * glimports.h
- *
- */
-
-#ifndef __gluimports_h_
-#define __gluimports_h_
-
-#include "mystdlib.h"
-#include "mystdio.h"
-
-#endif /* __gluimports_h_ */
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include "gluos.h"
-#include <GL/gl.h>
-#include <GL/glu.h>
-#include <stdio.h>
-#include "glimports.h"
-#include "glrenderer.h"
-#include "nurbsconsts.h"
-
-//#define DOWN_LOAD_NURBS
-#ifdef DOWN_LOAD_NURBS
-
-#include "oglTrimNurbs.h"
-static int surfcount = 0;
-static oglTrimNurbs* otn = NULL;
-nurbSurf* tempNurb = NULL;
-oglTrimLoops* tempTrim = NULL;
-#endif
-
-
-//for LOD
-extern "C" {void glu_LOD_eval_list(GLUnurbs *nurb, int level);}
-
-void glu_LOD_eval_list(GLUnurbs *nurb, int level)
-{
- nurb->LOD_eval_list(level);
-}
-
-GLUnurbs * GLAPIENTRY
-gluNewNurbsRenderer(void)
-{
- GLUnurbs *t;
-
- t = new GLUnurbs();
- return t;
-}
-
-void GLAPIENTRY
-gluDeleteNurbsRenderer(GLUnurbs *r)
-{
- delete r;
-}
-
-extern "C"
-void GLAPIENTRY
-
-gluDeleteNurbsTessellatorEXT(GLUnurbsObj *r)
-{
- delete r;
-}
-
-void GLAPIENTRY
-gluBeginSurface(GLUnurbs *r)
-{
-#ifdef DOWN_LOAD_NURBS
-surfcount++;
-tempTrim = OTL_make(10,10);
-#endif
- r->bgnsurface(0);
-}
-
-void GLAPIENTRY
-gluBeginCurve(GLUnurbs *r)
-{
- r->bgncurve(0);
-}
-
-void GLAPIENTRY
-gluEndCurve(GLUnurbs *r)
-{
- r->endcurve();
-}
-
-void GLAPIENTRY
-gluEndSurface(GLUnurbs *r)
-{
-#ifdef DOWN_LOAD_NURBS
-if(surfcount == 1)
- otn = OTN_make(1);
-OTN_insert(otn, tempNurb, tempTrim);
-if(surfcount >= 1)
-{
-#ifdef DEBUG
-printf("write file\n");
-#endif
-OTN_write(otn, "out.otn");
-
-}
-#endif
-
- r->endsurface();
-}
-
-void GLAPIENTRY
-gluBeginTrim(GLUnurbs *r)
-{
-#ifdef DOWN_LOAD_NURBS
-OTL_bgnTrim(tempTrim);
-#endif
-
- r->bgntrim();
-}
-
-void GLAPIENTRY
-gluEndTrim(GLUnurbs *r)
-{
-#ifdef DOWN_LOAD_NURBS
-OTL_endTrim(tempTrim);
-#endif
- r->endtrim();
-}
-
-void GLAPIENTRY
-gluPwlCurve(GLUnurbs *r, GLint count, INREAL array[],
- GLint stride, GLenum type)
-{
-#ifdef DOWN_LOAD_NURBS
-OTL_pwlCurve(tempTrim, count, array, stride, type);
-#endif
-
- int realType;
- switch(type) {
- case GLU_MAP1_TRIM_2:
- realType = N_P2D;
- break;
- case GLU_MAP1_TRIM_3:
- realType = N_P2DR;
- break;
- default:
- realType = type;
- break;
- }
- r->pwlcurve(count, array, sizeof(INREAL) * stride, realType);
-}
-
-void GLAPIENTRY
-gluNurbsCurve(GLUnurbs *r, GLint nknots, INREAL knot[], GLint stride,
- INREAL ctlarray[], GLint order, GLenum type)
-{
-#ifdef DOWN_LOAD_NURBS
-OTL_nurbsCurve(tempTrim, nknots, knot, stride, ctlarray, order, type);
-#endif
-
- int realType;
-
- switch(type) {
- case GLU_MAP1_TRIM_2:
- realType = N_P2D;
- break;
- case GLU_MAP1_TRIM_3:
- realType = N_P2DR;
- break;
- default:
- realType = type;
- break;
- }
-
- r->nurbscurve(nknots, knot, sizeof(INREAL) * stride, ctlarray, order,
- realType);
-}
-
-void GLAPIENTRY
-gluNurbsSurface(GLUnurbs *r, GLint sknot_count, GLfloat *sknot,
- GLint tknot_count, GLfloat *tknot,
- GLint s_stride, GLint t_stride,
- GLfloat *ctlarray, GLint sorder, GLint torder,
- GLenum type)
-{
-#ifdef DOWN_LOAD_NURBS
- {
- int dimension;
- switch(type){
- case GL_MAP2_VERTEX_3:
- dimension = 3;
- break;
- case GL_MAP2_VERTEX_4:
- dimension = 4;
- break;
- default:
- fprintf(stderr, "error in glinterface.c++, type no implemented\n");
- exit(1);
- }
-tempNurb = nurbSurfMake(sknot_count, sknot,
- tknot_count, tknot,
- sorder, torder,
- dimension,
- ctlarray,
- s_stride, t_stride);
-
- }
-#endif
-
- r->nurbssurface(sknot_count, sknot, tknot_count, tknot,
- sizeof(INREAL) * s_stride, sizeof(INREAL) * t_stride,
- ctlarray, sorder, torder, type);
-}
-
-void GLAPIENTRY
-gluLoadSamplingMatrices(GLUnurbs *r, const GLfloat modelMatrix[16],
- const GLfloat projMatrix[16],
- const GLint viewport[4])
-{
- r->useGLMatrices(modelMatrix, projMatrix, viewport);
-}
-
-void GLAPIENTRY
-gluNurbsProperty(GLUnurbs *r, GLenum property, GLfloat value)
-{
- GLfloat nurbsValue;
-
- switch (property) {
- case GLU_AUTO_LOAD_MATRIX:
- r->setautoloadmode(value);
- return;
-
- case GLU_CULLING:
- if (value != 0.0) {
- nurbsValue = N_CULLINGON;
- } else {
- nurbsValue = N_NOCULLING;
- }
- r->setnurbsproperty(GL_MAP2_VERTEX_3, N_CULLING, nurbsValue);
- r->setnurbsproperty(GL_MAP2_VERTEX_4, N_CULLING, nurbsValue);
- r->setnurbsproperty(GL_MAP1_VERTEX_3, N_CULLING, nurbsValue);
- r->setnurbsproperty(GL_MAP1_VERTEX_4, N_CULLING, nurbsValue);
- return;
-
- case GLU_SAMPLING_METHOD:
- if (value == GLU_PATH_LENGTH) {
- nurbsValue = N_PATHLENGTH;
- } else if (value == GLU_PARAMETRIC_ERROR) {
- nurbsValue = N_PARAMETRICDISTANCE;
- } else if (value == GLU_DOMAIN_DISTANCE) {
- nurbsValue = N_DOMAINDISTANCE;
- r->set_is_domain_distance_sampling(1); //optimzing untrimmed case
-
- } else if (value == GLU_OBJECT_PARAMETRIC_ERROR) {
- nurbsValue = N_OBJECTSPACE_PARA;
- r->setautoloadmode( 0.0 );
- r->setSamplingMatrixIdentity();
- } else if (value == GLU_OBJECT_PATH_LENGTH) {
- nurbsValue = N_OBJECTSPACE_PATH;
- r->setautoloadmode( 0.0 );
- r->setSamplingMatrixIdentity();
- } else {
- r->postError(GLU_INVALID_VALUE);
- return;
- }
-
- r->setnurbsproperty(GL_MAP2_VERTEX_3, N_SAMPLINGMETHOD, nurbsValue);
- r->setnurbsproperty(GL_MAP2_VERTEX_4, N_SAMPLINGMETHOD, nurbsValue);
- r->setnurbsproperty(GL_MAP1_VERTEX_3, N_SAMPLINGMETHOD, nurbsValue);
- r->setnurbsproperty(GL_MAP1_VERTEX_4, N_SAMPLINGMETHOD, nurbsValue);
- return;
-
- case GLU_SAMPLING_TOLERANCE:
- r->setnurbsproperty(GL_MAP2_VERTEX_3, N_PIXEL_TOLERANCE, value);
- r->setnurbsproperty(GL_MAP2_VERTEX_4, N_PIXEL_TOLERANCE, value);
- r->setnurbsproperty(GL_MAP1_VERTEX_3, N_PIXEL_TOLERANCE, value);
- r->setnurbsproperty(GL_MAP1_VERTEX_4, N_PIXEL_TOLERANCE, value);
- return;
-
- case GLU_PARAMETRIC_TOLERANCE:
- r->setnurbsproperty(GL_MAP2_VERTEX_3, N_ERROR_TOLERANCE, value);
- r->setnurbsproperty(GL_MAP2_VERTEX_4, N_ERROR_TOLERANCE, value);
- r->setnurbsproperty(GL_MAP1_VERTEX_3, N_ERROR_TOLERANCE, value);
- r->setnurbsproperty(GL_MAP1_VERTEX_4, N_ERROR_TOLERANCE, value);
- return;
-
-
- case GLU_DISPLAY_MODE:
-
- if (value == GLU_FILL) {
- nurbsValue = N_FILL;
- } else if (value == GLU_OUTLINE_POLYGON) {
- nurbsValue = N_OUTLINE_POLY;
- } else if (value == GLU_OUTLINE_PATCH) {
- nurbsValue = N_OUTLINE_PATCH;
- } else {
- r->postError(GLU_INVALID_VALUE);
- return;
- }
- r->setnurbsproperty(N_DISPLAY, nurbsValue);
-
- break;
-
- case GLU_U_STEP:
- r->setnurbsproperty(GL_MAP1_VERTEX_3, N_S_STEPS, value);
- r->setnurbsproperty(GL_MAP1_VERTEX_4, N_S_STEPS, value);
- r->setnurbsproperty(GL_MAP2_VERTEX_3, N_S_STEPS, value);
- r->setnurbsproperty(GL_MAP2_VERTEX_4, N_S_STEPS, value);
-
- //added for optimizing untrimmed case
- r->set_domain_distance_u_rate(value);
- break;
-
- case GLU_V_STEP:
- r->setnurbsproperty(GL_MAP1_VERTEX_3, N_T_STEPS, value);
- r->setnurbsproperty(GL_MAP1_VERTEX_4, N_T_STEPS, value);
- r->setnurbsproperty(GL_MAP2_VERTEX_3, N_T_STEPS, value);
- r->setnurbsproperty(GL_MAP2_VERTEX_4, N_T_STEPS, value);
-
- //added for optimizing untrimmed case
- r->set_domain_distance_v_rate(value);
- break;
-
- case GLU_NURBS_MODE:
- if(value == GLU_NURBS_RENDERER)
- r->put_callbackFlag(0);
- else if(value == GLU_NURBS_TESSELLATOR)
- r->put_callbackFlag(1);
- else
- r->postError(GLU_INVALID_ENUM);
- break;
-
- default:
- r->postError(GLU_INVALID_ENUM);
- return;
- }
-}
-
-void GLAPIENTRY
-gluGetNurbsProperty(GLUnurbs *r, GLenum property, GLfloat *value)
-{
- GLfloat nurbsValue;
-
- switch(property) {
- case GLU_AUTO_LOAD_MATRIX:
- if (r->getautoloadmode()) {
- *value = GL_TRUE;
- } else {
- *value = GL_FALSE;
- }
- break;
- case GLU_CULLING:
- r->getnurbsproperty(GL_MAP2_VERTEX_3, N_CULLING, &nurbsValue);
- if (nurbsValue == N_CULLINGON) {
- *value = GL_TRUE;
- } else {
- *value = GL_FALSE;
- }
- break;
- case GLU_SAMPLING_METHOD:
- r->getnurbsproperty(GL_MAP2_VERTEX_3, N_SAMPLINGMETHOD, value);
- if(*value == N_PATHLENGTH)
- *value = GLU_PATH_LENGTH;
- else if(*value == N_PARAMETRICDISTANCE)
- *value = GLU_PARAMETRIC_ERROR;
- else if(*value == N_DOMAINDISTANCE)
- *value = GLU_DOMAIN_DISTANCE;
- else if(*value == N_OBJECTSPACE_PATH)
- *value = GLU_OBJECT_PATH_LENGTH;
- else if(*value == N_OBJECTSPACE_PARA)
- *value = GLU_OBJECT_PARAMETRIC_ERROR;
- break;
- case GLU_SAMPLING_TOLERANCE:
- r->getnurbsproperty(GL_MAP2_VERTEX_3, N_PIXEL_TOLERANCE, value);
- break;
- case GLU_PARAMETRIC_TOLERANCE:
- r->getnurbsproperty(GL_MAP2_VERTEX_3, N_ERROR_TOLERANCE, value);
- break;
-
- case GLU_U_STEP:
- r->getnurbsproperty(GL_MAP2_VERTEX_3, N_S_STEPS, value);
- break;
- case GLU_V_STEP:
- r->getnurbsproperty(GL_MAP2_VERTEX_3, N_T_STEPS, value);
- break;
- case GLU_DISPLAY_MODE:
- r->getnurbsproperty(N_DISPLAY, &nurbsValue);
- if (nurbsValue == N_FILL) {
- *value = GLU_FILL;
- } else if (nurbsValue == N_OUTLINE_POLY) {
- *value = GLU_OUTLINE_POLYGON;
- } else {
- *value = GLU_OUTLINE_PATCH;
- }
- break;
-
- case GLU_NURBS_MODE:
- if(r->is_callback())
- *value = GLU_NURBS_TESSELLATOR;
- else
- *value = GLU_NURBS_RENDERER;
- break;
-
- default:
- r->postError(GLU_INVALID_ENUM);
- return;
- }
-}
-
-extern "C" void GLAPIENTRY
-gluNurbsCallback(GLUnurbs *r, GLenum which, _GLUfuncptr fn )
-{
- switch (which) {
- case GLU_NURBS_BEGIN:
- case GLU_NURBS_END:
- case GLU_NURBS_VERTEX:
- case GLU_NURBS_NORMAL:
- case GLU_NURBS_TEXTURE_COORD:
- case GLU_NURBS_COLOR:
- case GLU_NURBS_BEGIN_DATA:
- case GLU_NURBS_END_DATA:
- case GLU_NURBS_VERTEX_DATA:
- case GLU_NURBS_NORMAL_DATA:
- case GLU_NURBS_TEXTURE_COORD_DATA:
- case GLU_NURBS_COLOR_DATA:
- r->putSurfCallBack(which, fn);
- break;
-
- case GLU_NURBS_ERROR:
- r->errorCallback = (void (APIENTRY *)( GLenum e )) fn;
- break;
- default:
- r->postError(GLU_INVALID_ENUM);
- return;
- }
-}
-
-extern "C"
-void GLAPIENTRY
-gluNurbsCallbackDataEXT(GLUnurbs* r, void* userData)
-{
- r->setNurbsCallbackData(userData);
-}
-
-extern "C"
-void GLAPIENTRY
-gluNurbsCallbackData(GLUnurbs* r, void* userData)
-{
- gluNurbsCallbackDataEXT(r,userData);
-}
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include "gluos.h"
-#include "glimports.h"
-#include "glrenderer.h"
-
-GLUnurbs::GLUnurbs()
- : NurbsTessellator(curveEvaluator, surfaceEvaluator)
-{
- redefineMaps();
- defineMap(GL_MAP2_NORMAL, 0, 3);
- defineMap(GL_MAP1_NORMAL, 0, 3);
- defineMap(GL_MAP2_TEXTURE_COORD_1, 0, 1);
- defineMap(GL_MAP1_TEXTURE_COORD_1, 0, 1);
- defineMap(GL_MAP2_TEXTURE_COORD_2, 0, 2);
- defineMap(GL_MAP1_TEXTURE_COORD_2, 0, 2);
- defineMap(GL_MAP2_TEXTURE_COORD_3, 0, 3);
- defineMap(GL_MAP1_TEXTURE_COORD_3, 0, 3);
- defineMap(GL_MAP2_TEXTURE_COORD_4, 1, 4);
- defineMap(GL_MAP1_TEXTURE_COORD_4, 1, 4);
- defineMap(GL_MAP2_VERTEX_4, 1, 4);
- defineMap(GL_MAP1_VERTEX_4, 1, 4);
- defineMap(GL_MAP2_VERTEX_3, 0, 3);
- defineMap(GL_MAP1_VERTEX_3, 0, 3);
- defineMap(GL_MAP2_COLOR_4, 0, 4);
- defineMap(GL_MAP1_COLOR_4, 0, 4);
- defineMap(GL_MAP2_INDEX, 0, 1);
- defineMap(GL_MAP1_INDEX, 0, 1);
-
- setnurbsproperty(GL_MAP1_VERTEX_3, N_SAMPLINGMETHOD, (float) N_PATHLENGTH);
- setnurbsproperty(GL_MAP1_VERTEX_4, N_SAMPLINGMETHOD, (float) N_PATHLENGTH);
- setnurbsproperty(GL_MAP2_VERTEX_3, N_SAMPLINGMETHOD, (float) N_PATHLENGTH);
- setnurbsproperty(GL_MAP2_VERTEX_4, N_SAMPLINGMETHOD, (float) N_PATHLENGTH);
-
- setnurbsproperty(GL_MAP1_VERTEX_3, N_PIXEL_TOLERANCE, (float) 50.0);
- setnurbsproperty(GL_MAP1_VERTEX_4, N_PIXEL_TOLERANCE, (float) 50.0);
- setnurbsproperty(GL_MAP2_VERTEX_3, N_PIXEL_TOLERANCE, (float) 50.0);
- setnurbsproperty(GL_MAP2_VERTEX_4, N_PIXEL_TOLERANCE, (float) 50.0);
-
- setnurbsproperty(GL_MAP1_VERTEX_3, N_ERROR_TOLERANCE, (float) 0.50);
- setnurbsproperty(GL_MAP1_VERTEX_4, N_ERROR_TOLERANCE, (float) 0.50);
- setnurbsproperty(GL_MAP2_VERTEX_3, N_ERROR_TOLERANCE, (float) 0.50);
- setnurbsproperty(GL_MAP2_VERTEX_4, N_ERROR_TOLERANCE, (float) 0.50);
-
- setnurbsproperty(GL_MAP1_VERTEX_3, N_S_STEPS, (float) 100.0);
- setnurbsproperty(GL_MAP1_VERTEX_4, N_S_STEPS, (float) 100.0);
- setnurbsproperty(GL_MAP2_VERTEX_3, N_S_STEPS, (float) 100.0);
- setnurbsproperty(GL_MAP2_VERTEX_4, N_S_STEPS, (float) 100.0);
-
- //added for optimizing untrimmed case
- set_domain_distance_u_rate(100.0);
-
- setnurbsproperty(GL_MAP1_VERTEX_3, N_T_STEPS, (float) 100.0);
- setnurbsproperty(GL_MAP1_VERTEX_4, N_T_STEPS, (float) 100.0);
- setnurbsproperty(GL_MAP2_VERTEX_3, N_T_STEPS, (float) 100.0);
- setnurbsproperty(GL_MAP2_VERTEX_4, N_T_STEPS, (float) 100.0);
-
- //added for optimizing untrimmed case
- set_domain_distance_v_rate(100.0);
- set_is_domain_distance_sampling(0); //since the default is path_length
-
- //default autoloadmode is true
- autoloadmode = 1;
-
- //default callbackFlag is 0
- callbackFlag = 0;
-
- errorCallback = NULL;
-}
-
-void
-GLUnurbs::bgnrender(void)
-{
- if (autoloadmode) {
- loadGLMatrices();
- }
-}
-
-void
-GLUnurbs::endrender(void)
-{
-}
-
-void
-GLUnurbs::errorHandler(int i)
-{
- int gluError;
-
- gluError = i + (GLU_NURBS_ERROR1 - 1);
- postError( gluError );
-}
-
-void
-GLUnurbs::loadGLMatrices(void)
-{
- GLfloat vmat[4][4];
- GLint viewport[4];
-
- grabGLMatrix((GLfloat (*)[4]) vmat);
- loadCullingMatrix((GLfloat (*)[4]) vmat);
- ::glGetIntegerv((GLenum) GL_VIEWPORT, (GLint *) viewport);
- loadSamplingMatrix((const GLfloat (*)[4]) vmat, (const GLint *) viewport);
-}
-
-void
-GLUnurbs::useGLMatrices(const GLfloat modelMatrix[16],
- const GLfloat projMatrix[16],
- const GLint viewport[4])
-{
- GLfloat vmat[4][4];
-
- multmatrix4d(vmat, (const GLfloat (*)[4]) modelMatrix,
- (const GLfloat (*)[4]) projMatrix);
- loadCullingMatrix((GLfloat (*)[4]) vmat);
- loadSamplingMatrix((const GLfloat (*)[4]) vmat, (const GLint *) viewport);
-}
-
-/*--------------------------------------------------------------------------
- * grabGLMatrix
- *--------------------------------------------------------------------------
- */
-
-void
-GLUnurbs::grabGLMatrix(GLfloat vmat[4][4])
-{
- GLfloat m1[4][4], m2[4][4];
-
- ::glGetFloatv((GLenum) GL_MODELVIEW_MATRIX, (GLfloat *) &(m1[0][0]));
- ::glGetFloatv((GLenum) GL_PROJECTION_MATRIX, (GLfloat *) &(m2[0][0]));
- multmatrix4d((GLfloat (*)[4]) vmat,
- (const GLfloat (*)[4]) m1, (const GLfloat (*)[4]) m2);
-}
-
-//for object space tesselation: view independent
-void
-GLUnurbs::setSamplingMatrixIdentity( void )
-{
- INREAL smat[4][4] = {
- {1,0,0,0},
- {0,1,0,0},
- {0,0,1,0},
- {0,0,0,1}
- };
- const long rstride = sizeof(smat[0]) / sizeof(smat[0][0]);
- const long cstride = 1;
-
- setnurbsproperty(GL_MAP1_VERTEX_3, N_SAMPLINGMATRIX, &smat[0][0], rstride,
- cstride);
- setnurbsproperty(GL_MAP1_VERTEX_4, N_SAMPLINGMATRIX, &smat[0][0], rstride,
- cstride);
- setnurbsproperty(GL_MAP2_VERTEX_3, N_SAMPLINGMATRIX, &smat[0][0], rstride,
- cstride);
- setnurbsproperty(GL_MAP2_VERTEX_4, N_SAMPLINGMATRIX, &smat[0][0], rstride,
- cstride);
-}
-
-
-void
-GLUnurbs::loadSamplingMatrix(const GLfloat vmat[4][4],
- const GLint viewport[4])
-{
-
- /* rescale the mapping to correspond to pixels in x/y */
- REAL xsize = 0.5 * (REAL) (viewport[2]);
- REAL ysize = 0.5 * (REAL) (viewport[3]);
-
- INREAL smat[4][4];
- smat[0][0] = vmat[0][0] * xsize;
- smat[1][0] = vmat[1][0] * xsize;
- smat[2][0] = vmat[2][0] * xsize;
- smat[3][0] = vmat[3][0] * xsize;
-
- smat[0][1] = vmat[0][1] * ysize;
- smat[1][1] = vmat[1][1] * ysize;
- smat[2][1] = vmat[2][1] * ysize;
- smat[3][1] = vmat[3][1] * ysize;
-
- smat[0][2] = 0.0;
- smat[1][2] = 0.0;
- smat[2][2] = 0.0;
- smat[3][2] = 0.0;
-
- smat[0][3] = vmat[0][3];
- smat[1][3] = vmat[1][3];
- smat[2][3] = vmat[2][3];
- smat[3][3] = vmat[3][3];
-
- const long rstride = sizeof(smat[0]) / sizeof(smat[0][0]);
- const long cstride = 1;
-
- setnurbsproperty(GL_MAP1_VERTEX_3, N_SAMPLINGMATRIX, &smat[0][0], rstride,
- cstride);
- setnurbsproperty(GL_MAP1_VERTEX_4, N_SAMPLINGMATRIX, &smat[0][0], rstride,
- cstride);
- setnurbsproperty(GL_MAP2_VERTEX_3, N_SAMPLINGMATRIX, &smat[0][0], rstride,
- cstride);
- setnurbsproperty(GL_MAP2_VERTEX_4, N_SAMPLINGMATRIX, &smat[0][0], rstride,
- cstride);
-}
-
-void
-GLUnurbs::loadCullingMatrix(GLfloat vmat[4][4])
-{
- INREAL cmat[4][4];
-
- cmat[0][0] = vmat[0][0];
- cmat[0][1] = vmat[0][1];
- cmat[0][2] = vmat[0][2];
- cmat[0][3] = vmat[0][3];
-
- cmat[1][0] = vmat[1][0];
- cmat[1][1] = vmat[1][1];
- cmat[1][2] = vmat[1][2];
- cmat[1][3] = vmat[1][3];
-
- cmat[2][0] = vmat[2][0];
- cmat[2][1] = vmat[2][1];
- cmat[2][2] = vmat[2][2];
- cmat[2][3] = vmat[2][3];
-
- cmat[3][0] = vmat[3][0];
- cmat[3][1] = vmat[3][1];
- cmat[3][2] = vmat[3][2];
- cmat[3][3] = vmat[3][3];
-
- const long rstride = sizeof(cmat[0]) / sizeof(cmat[0][0]);
- const long cstride = 1;
-
- setnurbsproperty(GL_MAP2_VERTEX_3, N_CULLINGMATRIX, &cmat[0][0], rstride,
- cstride);
- setnurbsproperty(GL_MAP2_VERTEX_4, N_CULLINGMATRIX, &cmat[0][0], rstride,
- cstride);
- //added for curves by zl
- setnurbsproperty(GL_MAP1_VERTEX_3, N_CULLINGMATRIX, &cmat[0][0], rstride,
- cstride);
- setnurbsproperty(GL_MAP1_VERTEX_4, N_CULLINGMATRIX, &cmat[0][0], rstride,
- cstride);
-}
-
-/*---------------------------------------------------------------------
- * A = B * MAT ; transform a 4d vector through a 4x4 matrix
- *---------------------------------------------------------------------
- */
-void
-GLUnurbs::transform4d(GLfloat A[4], GLfloat B[4], GLfloat mat[4][4])
-{
-
- A[0] = B[0]*mat[0][0] + B[1]*mat[1][0] + B[2]*mat[2][0] + B[3]*mat[3][0];
- A[1] = B[0]*mat[0][1] + B[1]*mat[1][1] + B[2]*mat[2][1] + B[3]*mat[3][1];
- A[2] = B[0]*mat[0][2] + B[1]*mat[1][2] + B[2]*mat[2][2] + B[3]*mat[3][2];
- A[3] = B[0]*mat[0][3] + B[1]*mat[1][3] + B[2]*mat[2][3] + B[3]*mat[3][3];
-}
-
-/*---------------------------------------------------------------------
- * new = [left][right] ; multiply two matrices together
- *---------------------------------------------------------------------
- */
-void
-GLUnurbs::multmatrix4d (GLfloat n[4][4], const GLfloat left[4][4],
- const GLfloat right[4][4])
-{
- transform4d ((GLfloat *) n[0],(GLfloat *) left[0],(GLfloat (*)[4]) right);
- transform4d ((GLfloat *) n[1],(GLfloat *) left[1],(GLfloat (*)[4]) right);
- transform4d ((GLfloat *) n[2],(GLfloat *) left[2],(GLfloat (*)[4]) right);
- transform4d ((GLfloat *) n[3],(GLfloat *) left[3],(GLfloat (*)[4]) right);
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * glrenderer.h
- *
- */
-
-#ifndef __gluglrenderer_h_
-#define __gluglrenderer_h_
-
-#include <GL/gl.h>
-#include <GL/glu.h>
-#include "nurbstess.h"
-#include "glsurfeval.h"
-#include "glcurveval.h"
-
-extern "C" {
- typedef void (APIENTRY *errorCallbackType)( GLenum );
-}
-
-class GLUnurbs : public NurbsTessellator {
-
-public:
- GLUnurbs( void );
- void loadGLMatrices( void );
- void useGLMatrices( const GLfloat modelMatrix[16],
- const GLfloat projMatrix[16],
- const GLint viewport[4] );
- void setSamplingMatrixIdentity( void );
-
- void errorHandler( int );
- void bgnrender( void );
- void endrender( void );
- void setautoloadmode( INREAL value )
- {
-
- if (value) autoloadmode = GL_TRUE;
- else autoloadmode = GL_FALSE;
-
- }
- GLboolean getautoloadmode( void ) { return autoloadmode; }
-
- errorCallbackType errorCallback;
- void postError( int which )
- { if (errorCallback) (errorCallback)( (GLenum)which ); }
-#ifdef _WIN32
- void putSurfCallBack(GLenum which, void (GLAPIENTRY *fn)() )
-#else
- void putSurfCallBack(GLenum which, _GLUfuncptr fn )
-#endif
- {
- curveEvaluator.putCallBack(which, fn);
- surfaceEvaluator.putCallBack(which, fn);
- }
-
- int get_vertices_call_back()
- {
- return surfaceEvaluator.get_vertices_call_back();
- }
-
- void put_vertices_call_back(int flag)
- {
- surfaceEvaluator.put_vertices_call_back(flag);
- }
-
- int get_callback_auto_normal()
- {
- return surfaceEvaluator.get_callback_auto_normal();
- }
-
- void put_callback_auto_normal(int flag)
- {
- surfaceEvaluator.put_callback_auto_normal(flag);
- }
-
- void setNurbsCallbackData(void* userData)
- {
- curveEvaluator.set_callback_userData(userData);
- surfaceEvaluator.set_callback_userData(userData);
- }
-
-
- //for LOD
- void LOD_eval_list(int level)
- {
- surfaceEvaluator.LOD_eval_list(level);
- }
-
- //NEWCALLBACK
- int is_callback()
- {
- return callbackFlag;
- }
- void put_callbackFlag(int flag)
- {
- callbackFlag = flag;
- surfaceEvaluator.put_vertices_call_back(flag);
- curveEvaluator.put_vertices_call_back(flag);
- }
-
-private:
- GLboolean autoloadmode;
- OpenGLSurfaceEvaluator surfaceEvaluator;
- OpenGLCurveEvaluator curveEvaluator;
-
- void loadSamplingMatrix( const GLfloat vmat[4][4],
- const GLint viewport[4] );
- void loadCullingMatrix( GLfloat vmat[4][4] );
- static void grabGLMatrix( GLfloat vmat[4][4] );
- static void transform4d( GLfloat A[4], GLfloat B[4],
- GLfloat mat[4][4] );
- static void multmatrix4d( GLfloat n[4][4], const GLfloat left[4][4],
- const GLfloat right[4][4] );
-
- int callbackFlag;
-};
-
-#endif /* __gluglrenderer_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * glsurfeval.c++
- *
- */
-
-/* Polynomial Evaluator Interface */
-#include "gluos.h"
-#include <stdio.h>
-#include "glimports.h"
-#include "glrenderer.h"
-#include "glsurfeval.h"
-#include "nurbsconsts.h"
-#include "bezierPatchMesh.h"
-
-
-//extern int surfcount;
-//int surfcount=0;
-
-/*#define USE_INTERNAL_EVAL*/ //use internal evaluator
-
-/*whether do evaluation or not*/
-/*#define NO_EVALUATION*/
-
-//#define USE_LOD //for LOD test, have to turn on USE_LOD in insurfeval.c++ too
-
-/*for statistics*/
-//#define STATISTICS
-#ifdef STATISTICS
-static int STAT_num_of_triangles=0;
-static int STAT_num_of_eval_vertices=0;
-static int STAT_num_of_quad_strips=0;
-#endif
-
-/*for output triangles*/
-/*#define OUTPUT_TRIANGLES*/
-
-
-/*#define FOR_CHRIS*/
-#ifdef FOR_CHRIS
-extern "C" { void evalUStripExt(int n_upper, REAL v_upper, REAL* upper_val,
- int n_lower, REAL v_lower, REAL* lower_val);}
-
-extern "C" { void evalVStripExt(int n_left, REAL u_left, REAL* left_val,
- int n_right, REAL u_right, REAL* right_val);
- }
-#endif
-
-
-/**************begin for LOD_eval_list***********/
-void OpenGLSurfaceEvaluator::LOD_eval_list(int level)
-{
- if(level == 0)
- LOD_eval_level = 1;
- else if(level == 1)
- LOD_eval_level = 2;
- else if(level == 2)
- LOD_eval_level = 4;
- else
- LOD_eval_level = 8;
-
- inBPMListEvalEM(global_bpm);
-}
-
-
-OpenGLSurfaceEvaluator::OpenGLSurfaceEvaluator()
-{
- int i;
-
- for (i=0; i<VERTEX_CACHE_SIZE; i++) {
- vertexCache[i] = new StoredVertex;
- }
- tmeshing = 0;
- which = 0;
- vcount = 0;
-
- global_uorder = 0;
- global_vorder = 0;
- global_uprime = -1.0;
- global_vprime = -1.0;
- global_vprime_BV = -1.0;
- global_uprime_BU = -1.0;
- global_uorder_BU = 0;
- global_vorder_BU = 0;
- global_uorder_BV = 0;
- global_vorder_BV = 0;
- global_baseData = NULL;
-
- global_bpm = NULL;
- output_triangles = 0; //don't output triangles by default
-
- //no default callback functions
- beginCallBackN = NULL;
- endCallBackN = NULL;
- vertexCallBackN = NULL;
- normalCallBackN = NULL;
- colorCallBackN = NULL;
- texcoordCallBackN = NULL;
- beginCallBackData = NULL;
- endCallBackData = NULL;
- vertexCallBackData = NULL;
- normalCallBackData = NULL;
- colorCallBackData = NULL;
- texcoordCallBackData = NULL;
-
- userData = NULL;
-
- auto_normal_flag = 0;
- callback_auto_normal = 0; //default of GLU_CALLBACK_AUTO_NORMAL is 0
- vertex_flag = 0;
- normal_flag = 0;
- color_flag = 0;
- texcoord_flag = 0;
-
- em_vertex.uprime = -1.0;
- em_vertex.vprime = -1.0;
- em_normal.uprime = -1.0;
- em_normal.vprime = -1.0;
- em_color.uprime = -1.0;
- em_color.vprime = -1.0;
- em_texcoord.uprime = -1.0;
- em_texcoord.vprime = -1.0;
-
-#ifdef USE_LOD
- LOD_eval_level = 1;
-#endif
-}
-
-OpenGLSurfaceEvaluator::~OpenGLSurfaceEvaluator()
-{
- for (int ii= 0; ii< VERTEX_CACHE_SIZE; ii++) {
- delete vertexCache[ii];
- vertexCache[ii]= 0;
- }
-}
-
-/*---------------------------------------------------------------------------
- * disable - turn off a map
- *---------------------------------------------------------------------------
- */
-void
-OpenGLSurfaceEvaluator::disable(long type)
-{
- glDisable((GLenum) type);
-}
-
-/*---------------------------------------------------------------------------
- * enable - turn on a map
- *---------------------------------------------------------------------------
- */
-void
-OpenGLSurfaceEvaluator::enable(long type)
-{
- glEnable((GLenum) type);
-}
-
-/*-------------------------------------------------------------------------
- * mapgrid2f - define a lattice of points with origin and offset
- *-------------------------------------------------------------------------
- */
-void
-OpenGLSurfaceEvaluator::mapgrid2f(long nu, REAL u0, REAL u1, long nv, REAL v0, REAL v1)
-{
-#ifdef USE_INTERNAL_EVAL
- inMapGrid2f((int) nu, (REAL) u0, (REAL) u1, (int) nv,
- (REAL) v0, (REAL) v1);
-#else
-
- if(output_triangles)
- {
- global_grid_u0 = u0;
- global_grid_u1 = u1;
- global_grid_nu = nu;
- global_grid_v0 = v0;
- global_grid_v1 = v1;
- global_grid_nv = nv;
- }
- else
- glMapGrid2d((GLint) nu, (GLdouble) u0, (GLdouble) u1, (GLint) nv,
- (GLdouble) v0, (GLdouble) v1);
-
-#endif
-}
-
-void
-OpenGLSurfaceEvaluator::polymode(long style)
-{
- if(! output_triangles)
- {
- switch(style) {
- default:
- case N_MESHFILL:
-
- glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_FILL);
- break;
- case N_MESHLINE:
- glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_LINE);
- break;
- case N_MESHPOINT:
- glPolygonMode((GLenum) GL_FRONT_AND_BACK, (GLenum) GL_POINT);
- break;
- }
- }
-}
-
-void
-OpenGLSurfaceEvaluator::bgnline(void)
-{
- if(output_triangles)
- bezierPatchMeshBeginStrip(global_bpm, GL_LINE_STRIP);
- else
- glBegin((GLenum) GL_LINE_STRIP);
-}
-
-void
-OpenGLSurfaceEvaluator::endline(void)
-{
- if(output_triangles)
- bezierPatchMeshEndStrip(global_bpm);
- else
- glEnd();
-}
-
-void
-OpenGLSurfaceEvaluator::range2f(long type, REAL *from, REAL *to)
-{
-}
-
-void
-OpenGLSurfaceEvaluator::domain2f(REAL ulo, REAL uhi, REAL vlo, REAL vhi)
-{
-}
-
-void
-OpenGLSurfaceEvaluator::bgnclosedline(void)
-{
- if(output_triangles)
- bezierPatchMeshBeginStrip(global_bpm, GL_LINE_LOOP);
- else
- glBegin((GLenum) GL_LINE_LOOP);
-}
-
-void
-OpenGLSurfaceEvaluator::endclosedline(void)
-{
- if(output_triangles)
- bezierPatchMeshEndStrip(global_bpm);
- else
- glEnd();
-}
-
-
-
-
-
-void
-OpenGLSurfaceEvaluator::bgntmesh(void)
-{
-
- tmeshing = 1;
- which = 0;
- vcount = 0;
-
- if(output_triangles)
- bezierPatchMeshBeginStrip(global_bpm, GL_TRIANGLES);
- else
- glBegin((GLenum) GL_TRIANGLES);
-
-}
-
-void
-OpenGLSurfaceEvaluator::swaptmesh(void)
-{
- which = 1 - which;
-
-}
-
-void
-OpenGLSurfaceEvaluator::endtmesh(void)
-{
- tmeshing = 0;
-
-
- if(output_triangles)
- bezierPatchMeshEndStrip(global_bpm);
- else
- glEnd();
-}
-
-void
-OpenGLSurfaceEvaluator::bgntfan(void)
-{
-
- if(output_triangles)
- bezierPatchMeshBeginStrip(global_bpm, GL_TRIANGLE_FAN);
- else
- glBegin((GLenum) GL_TRIANGLE_FAN);
-
-}
-void
-OpenGLSurfaceEvaluator::endtfan(void)
-{
- if(output_triangles)
- bezierPatchMeshEndStrip(global_bpm);
- else
- glEnd();
-}
-
-void
-OpenGLSurfaceEvaluator::evalUStrip(int n_upper, REAL v_upper, REAL* upper_val, int n_lower, REAL v_lower, REAL* lower_val)
-{
-#ifdef USE_INTERNAL_EVAL
- inEvalUStrip(n_upper, v_upper, upper_val,
- n_lower, v_lower, lower_val);
-#else
-
-#ifdef FOR_CHRIS
- evalUStripExt(n_upper, v_upper, upper_val,
- n_lower, v_lower, lower_val);
- return;
-
-#endif
- int i,j,k,l;
- REAL leftMostV[2];
-
- /*
- *the algorithm works by scanning from left to right.
- *leftMostV: the left most of the remaining verteces (on both upper and lower).
- * it could an element of upperVerts or lowerVerts.
- *i: upperVerts[i] is the first vertex to the right of leftMostV on upper line
- *j: lowerVerts[j] is the first vertex to the right of leftMostV on lower line
- */
-
- /*initialize i,j,and leftMostV
- */
- if(upper_val[0] <= lower_val[0])
- {
- i=1;
- j=0;
-
- leftMostV[0] = upper_val[0];
- leftMostV[1] = v_upper;
- }
- else
- {
- i=0;
- j=1;
-
- leftMostV[0] = lower_val[0];
- leftMostV[1] = v_lower;
-
- }
-
- /*the main loop.
- *the invariance is that:
- *at the beginning of each loop, the meaning of i,j,and leftMostV are
- *maintained
- */
- while(1)
- {
- if(i >= n_upper) /*case1: no more in upper*/
- {
- if(j<n_lower-1) /*at least two vertices in lower*/
- {
- bgntfan();
- coord2f(leftMostV[0], leftMostV[1]);
-// glNormal3fv(leftMostNormal);
-// glVertex3fv(leftMostXYZ);
-
- while(j<n_lower){
- coord2f(lower_val[j], v_lower);
-// glNormal3fv(lowerNormal[j]);
-// glVertex3fv(lowerXYZ[j]);
- j++;
-
- }
- endtfan();
- }
- break; /*exit the main loop*/
- }
- else if(j>= n_lower) /*case2: no more in lower*/
- {
- if(i<n_upper-1) /*at least two vertices in upper*/
- {
- bgntfan();
- coord2f(leftMostV[0], leftMostV[1]);
-// glNormal3fv(leftMostNormal);
-// glVertex3fv(leftMostXYZ);
-
- for(k=n_upper-1; k>=i; k--) /*reverse order for two-side lighting*/
- {
- coord2f(upper_val[k], v_upper);
-// glNormal3fv(upperNormal[k]);
-// glVertex3fv(upperXYZ[k]);
- }
-
- endtfan();
- }
- break; /*exit the main loop*/
- }
- else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output*/
- {
- if(upper_val[i] <= lower_val[j])
- {
- bgntfan();
- coord2f(lower_val[j], v_lower);
-// glNormal3fv(lowerNormal[j]);
-// glVertex3fv(lowerXYZ[j]);
-
- /*find the last k>=i such that
- *upperverts[k][0] <= lowerverts[j][0]
- */
- k=i;
-
- while(k<n_upper)
- {
- if(upper_val[k] > lower_val[j])
- break;
- k++;
-
- }
- k--;
-
-
- for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/
- {
- coord2f(upper_val[l], v_upper);
-// glNormal3fv(upperNormal[l]);
-// glVertex3fv(upperXYZ[l]);
-
- }
- coord2f(leftMostV[0], leftMostV[1]);
-// glNormal3fv(leftMostNormal);
-// glVertex3fv(leftMostXYZ);
-
- endtfan();
-
- /*update i and leftMostV for next loop
- */
- i = k+1;
-
- leftMostV[0] = upper_val[k];
- leftMostV[1] = v_upper;
-// leftMostNormal = upperNormal[k];
-// leftMostXYZ = upperXYZ[k];
- }
- else /*upperVerts[i][0] > lowerVerts[j][0]*/
- {
- bgntfan();
- coord2f(upper_val[i], v_upper);
-// glNormal3fv(upperNormal[i]);
-// glVertex3fv(upperXYZ[i]);
-
- coord2f(leftMostV[0], leftMostV[1]);
-// glNormal3fv(leftMostNormal);
-// glVertex3fv(leftMostXYZ);
-
-
- /*find the last k>=j such that
- *lowerverts[k][0] < upperverts[i][0]
- */
- k=j;
- while(k< n_lower)
- {
- if(lower_val[k] >= upper_val[i])
- break;
- coord2f(lower_val[k], v_lower);
-// glNormal3fv(lowerNormal[k]);
-// glVertex3fv(lowerXYZ[k]);
-
- k++;
- }
- endtfan();
-
- /*update j and leftMostV for next loop
- */
- j=k;
- leftMostV[0] = lower_val[j-1];
- leftMostV[1] = v_lower;
-
-// leftMostNormal = lowerNormal[j-1];
-// leftMostXYZ = lowerXYZ[j-1];
- }
- }
- }
- //clean up
-// free(upperXYZ);
-// free(lowerXYZ);
-// free(upperNormal);
-// free(lowerNormal);
-#endif
-
-}
-
-
-void
-OpenGLSurfaceEvaluator::evalVStrip(int n_left, REAL u_left, REAL* left_val, int n_right, REAL u_right, REAL* right_val)
-{
-#ifdef USE_INTERNAL_EVAL
- inEvalVStrip(n_left, u_left, left_val,
- n_right, u_right, right_val);
-#else
-
-#ifdef FOR_CHRIS
- evalVStripExt(n_left, u_left, left_val,
- n_right, u_right, right_val);
- return;
-
-#endif
-
- int i,j,k,l;
- REAL botMostV[2];
- /*
- *the algorithm works by scanning from bot to top.
- *botMostV: the bot most of the remaining verteces (on both left and right).
- * it could an element of leftVerts or rightVerts.
- *i: leftVerts[i] is the first vertex to the top of botMostV on left line
- *j: rightVerts[j] is the first vertex to the top of botMostV on rightline
- */
-
- /*initialize i,j,and botMostV
- */
- if(left_val[0] <= right_val[0])
- {
- i=1;
- j=0;
-
- botMostV[0] = u_left;
- botMostV[1] = left_val[0];
- }
- else
- {
- i=0;
- j=1;
-
- botMostV[0] = u_right;
- botMostV[1] = right_val[0];
- }
-
- /*the main loop.
- *the invariance is that:
- *at the beginning of each loop, the meaning of i,j,and botMostV are
- *maintained
- */
- while(1)
- {
- if(i >= n_left) /*case1: no more in left*/
- {
- if(j<n_right-1) /*at least two vertices in right*/
- {
- bgntfan();
- coord2f(botMostV[0], botMostV[1]);
- while(j<n_right){
- coord2f(u_right, right_val[j]);
-// glNormal3fv(rightNormal[j]);
-// glVertex3fv(rightXYZ[j]);
- j++;
-
- }
- endtfan();
- }
- break; /*exit the main loop*/
- }
- else if(j>= n_right) /*case2: no more in right*/
- {
- if(i<n_left-1) /*at least two vertices in left*/
- {
- bgntfan();
- coord2f(botMostV[0], botMostV[1]);
-// glNormal3fv(botMostNormal);
-// glVertex3fv(botMostXYZ);
-
- for(k=n_left-1; k>=i; k--) /*reverse order for two-side lighting*/
- {
- coord2f(u_left, left_val[k]);
-// glNormal3fv(leftNormal[k]);
-// glVertex3fv(leftXYZ[k]);
- }
-
- endtfan();
- }
- break; /*exit the main loop*/
- }
- else /* case3: neither is empty, plus the botMostV, there is at least one triangle to output*/
- {
- if(left_val[i] <= right_val[j])
- {
- bgntfan();
- coord2f(u_right, right_val[j]);
-// glNormal3fv(rightNormal[j]);
-// glVertex3fv(rightXYZ[j]);
-
- /*find the last k>=i such that
- *leftverts[k][0] <= rightverts[j][0]
- */
- k=i;
-
- while(k<n_left)
- {
- if(left_val[k] > right_val[j])
- break;
- k++;
-
- }
- k--;
-
-
- for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/
- {
- coord2f(u_left, left_val[l]);
-// glNormal3fv(leftNormal[l]);
-// glVertex3fv(leftXYZ[l]);
-
- }
- coord2f(botMostV[0], botMostV[1]);
-// glNormal3fv(botMostNormal);
-// glVertex3fv(botMostXYZ);
-
- endtfan();
-
- /*update i and botMostV for next loop
- */
- i = k+1;
-
- botMostV[0] = u_left;
- botMostV[1] = left_val[k];
-// botMostNormal = leftNormal[k];
-// botMostXYZ = leftXYZ[k];
- }
- else /*left_val[i] > right_val[j])*/
- {
- bgntfan();
- coord2f(u_left, left_val[i]);
-// glNormal3fv(leftNormal[i]);
-// glVertex3fv(leftXYZ[i]);
-
- coord2f(botMostV[0], botMostV[1]);
-// glNormal3fv(botMostNormal);
-// glVertex3fv(botMostXYZ);
-
-
- /*find the last k>=j such that
- *rightverts[k][0] < leftverts[i][0]
- */
- k=j;
- while(k< n_right)
- {
- if(right_val[k] >= left_val[i])
- break;
- coord2f(u_right, right_val[k]);
-// glNormal3fv(rightNormal[k]);
-// glVertex3fv(rightXYZ[k]);
-
- k++;
- }
- endtfan();
-
- /*update j and botMostV for next loop
- */
- j=k;
- botMostV[0] = u_right;
- botMostV[1] = right_val[j-1];
-
-// botMostNormal = rightNormal[j-1];
-// botMostXYZ = rightXYZ[j-1];
- }
- }
- }
- //clean up
-// free(leftXYZ);
-// free(leftNormal);
-// free(rightXYZ);
-// free(rightNormal);
-#endif
-}
-
-
-void
-OpenGLSurfaceEvaluator::bgnqstrip(void)
-{
- if(output_triangles)
- bezierPatchMeshBeginStrip(global_bpm, GL_QUAD_STRIP);
- else
- glBegin((GLenum) GL_QUAD_STRIP);
-
-#ifdef STATISTICS
- STAT_num_of_quad_strips++;
-#endif
-}
-
-void
-OpenGLSurfaceEvaluator::endqstrip(void)
-{
- if(output_triangles)
- bezierPatchMeshEndStrip(global_bpm);
- else
- glEnd();
-
-}
-
-/*-------------------------------------------------------------------------
- * bgnmap2f - preamble to surface definition and evaluations
- *-------------------------------------------------------------------------
- */
-void
-OpenGLSurfaceEvaluator::bgnmap2f(long)
-{
- if(output_triangles)
- {
- /*deallocate the space which may has been
- *allocated by global_bpm previously
- */
- if(global_bpm != NULL) {
- bezierPatchMeshListDelete(global_bpm);
- global_bpm = NULL;
- }
-
-
- /*
- auto_normal_flag = 1; //always output normal in callback mode.
- //we could have used the following code,
- //but Inspector doesn't have gl context
- //before it calls tessellator.
- //this way is temporary.
- */
- //NEWCALLBACK
- //if one of the two normal callback functions are set,
- //then set
- if(normalCallBackN != NULL ||
- normalCallBackData != NULL)
- auto_normal_flag = 1;
- else
- auto_normal_flag = 0;
-
- //initialize so that no maps initially
- vertex_flag = 0;
- normal_flag = 0;
- color_flag = 0;
- texcoord_flag = 0;
-
- /*
- if(glIsEnabled(GL_AUTO_NORMAL) == GL_TRUE)
- auto_normal_flag = 1;
- else if (callback_auto_normal == 1)
- auto_normal_flag = 1;
- else
- auto_normal_flag = 0;
- */
- glPushAttrib((GLbitfield) GL_EVAL_BIT);
-
- }
- else
- {
- glPushAttrib((GLbitfield) GL_EVAL_BIT);
-
- /*to avoid side effect, we restor the opengl state for GL_POLYGON_MODE
- */
- glGetIntegerv(GL_POLYGON_MODE, gl_polygon_mode);
- }
-
-}
-
-/*-------------------------------------------------------------------------
- * endmap2f - postamble to a map
- *-------------------------------------------------------------------------
- */
-void
-OpenGLSurfaceEvaluator::endmap2f(void)
-{
-
- if(output_triangles)
- {
- //bezierPatchMeshListDelDeg(global_bpm);
-
- // bezierPatchMeshListEval(global_bpm);
-
- //surfcount++;
- //printf("surfcount=%i\n", surfcount);
- //if(surfcount == 8) exit(0);
-
- inBPMListEvalEM(global_bpm);
-
-
-
-/*
- global_bpm = bezierPatchMeshListReverse(global_bpm);
- {
- float *vertex_array;
- float *normal_array;
- int *length_array;
- int *type_array;
- int num_strips;
- bezierPatchMeshListCollect(global_bpm, &vertex_array, &normal_array, &length_array, &type_array, &num_strips);
- drawStrips(vertex_array, normal_array, length_array, type_array, num_strips);
- free(vertex_array);
- free(normal_array);
- free(length_array);
- free(type_array);
- }
-*/
-
- //bezierPatchMeshListPrint(global_bpm);
- //bezierPatchMeshListDraw(global_bpm);
-
-// printf("num triangles=%i\n", bezierPatchMeshListNumTriangles(global_bpm));
-
-#ifdef USE_LOD
-#else
- bezierPatchMeshListDelete(global_bpm);
- global_bpm = NULL;
-#endif
- glPopAttrib();
- }
-else
- {
-#ifndef USE_LOD
- glPopAttrib();
-#endif
-
-#ifdef STATISTICS
- fprintf(stderr, "num_vertices=%i,num_triangles=%i,num_quads_strips=%i\n", STAT_num_of_eval_vertices,STAT_num_of_triangles,STAT_num_of_quad_strips);
-#endif
-
- /*to restore the gl_polygon_mode
- */
-#ifndef USE_LOD
- glPolygonMode( GL_FRONT, (GLenum) gl_polygon_mode[0]);
- glPolygonMode( GL_BACK, (GLenum) gl_polygon_mode[1]);
-#endif
-}
-
-}
-
-/*-------------------------------------------------------------------------
- * map2f - pass a desription of a surface map
- *-------------------------------------------------------------------------
- */
-void
-OpenGLSurfaceEvaluator::map2f(
- long _type,
- REAL _ulower, /* u lower domain coord */
- REAL _uupper, /* u upper domain coord */
- long _ustride, /* interpoint distance */
- long _uorder, /* parametric order */
- REAL _vlower, /* v lower domain coord */
- REAL _vupper, /* v upper domain coord */
- long _vstride, /* interpoint distance */
- long _vorder, /* parametric order */
- REAL *pts) /* control points */
-{
-#ifdef USE_INTERNAL_EVAL
- inMap2f((int) _type, (REAL) _ulower, (REAL) _uupper,
- (int) _ustride, (int) _uorder, (REAL) _vlower,
- (REAL) _vupper, (int) _vstride, (int) _vorder,
- (REAL *) pts);
-#else
-
-
-
- if(output_triangles)
- {
- if(global_bpm == NULL)
- global_bpm = bezierPatchMeshMake2(10,10);
- if(
- (global_bpm->bpatch == NULL &&
- (_type == GL_MAP2_VERTEX_3 || _type == GL_MAP2_VERTEX_4))
- ||
- (global_bpm->bpatch_normal == NULL &&
- (_type == GL_MAP2_NORMAL))
- ||
- (global_bpm->bpatch_color == NULL &&
- (_type == GL_MAP2_INDEX || _type == GL_MAP2_COLOR_4))
- ||
- (global_bpm->bpatch_texcoord == NULL &&
- (_type == GL_MAP2_TEXTURE_COORD_1 ||
- _type == GL_MAP2_TEXTURE_COORD_2 ||
- _type == GL_MAP2_TEXTURE_COORD_3 ||
- _type == GL_MAP2_TEXTURE_COORD_4 )
- ))
- {
- bezierPatchMeshPutPatch(global_bpm, (int) _type, _ulower, _uupper,(int) _ustride,(int) _uorder,_vlower, _vupper, (int) _vstride, (int) _vorder, pts);
- }
- else /*new surface patch (with multiple maps) starts*/
- {
- bezierPatchMesh *temp = bezierPatchMeshMake2(10,10);
- bezierPatchMeshPutPatch(temp, (int) _type, _ulower, _uupper,(int) _ustride,(int) _uorder,_vlower, _vupper, (int) _vstride, (int) _vorder, pts);
- global_bpm = bezierPatchMeshListInsert(global_bpm, temp);
-
- /*
- global_bpm = bezierPatchMeshListInsert(global_bpm,
- bezierPatchMeshMake(
- (int) _type, _ulower, _uupper,(int) _ustride, (int) _uorder, _vlower, _vupper, (int) _vstride, (int) _vorder, pts, 10, 10));
- */
- }
- }
- else /*not output triangles*/
- {
- glMap2f((GLenum) _type, (GLfloat) _ulower, (GLfloat) _uupper,
- (GLint) _ustride, (GLint) _uorder, (GLfloat) _vlower,
- (GLfloat) _vupper, (GLint) _vstride, (GLint) _vorder,
- (const GLfloat *) pts);
- }
-
-#endif
-}
-
-
-/*-------------------------------------------------------------------------
- * mapmesh2f - evaluate a mesh of points on lattice
- *-------------------------------------------------------------------------
- */
-void
-OpenGLSurfaceEvaluator::mapmesh2f(long style, long umin, long umax, long vmin, long vmax)
-{
-#ifdef NO_EVALUATION
-return;
-#endif
-
-#ifdef USE_INTERNAL_EVAL
- inEvalMesh2((int)umin, (int)vmin, (int)umax, (int)vmax);
-#else
-
-
-
-if(output_triangles)
-{
-#ifdef USE_LOD
- bezierPatchMeshBeginStrip(global_bpm, GL_POLYGON);
- bezierPatchMeshInsertUV(global_bpm, global_grid_u0, global_grid_v0);
- bezierPatchMeshInsertUV(global_bpm, global_grid_u1, global_grid_v1);
- bezierPatchMeshInsertUV(global_bpm, (REAL)global_grid_nu, (REAL)global_grid_nv);
- bezierPatchMeshInsertUV(global_bpm, (REAL)umin, (REAL)vmin);
- bezierPatchMeshInsertUV(global_bpm, (REAL)umax, (REAL)vmax);
- bezierPatchMeshEndStrip(global_bpm);
-
-#else
-
- REAL du, dv;
- long i,j;
- if(global_grid_nu == 0 || global_grid_nv == 0)
- return; /*no points need to be output*/
- du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu;
- dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv;
-
- if(global_grid_nu >= global_grid_nv){
-
- for(i=umin; i<umax; i++){
- REAL u1 = (i==global_grid_nu)? global_grid_u1:(global_grid_u0 + i*du);
- REAL u2 = ((i+1) == global_grid_nu)? global_grid_u1: (global_grid_u0+(i+1)*du);
-
- bgnqstrip();
- for(j=vmax; j>=vmin; j--){
- REAL v1 = (j == global_grid_nv)? global_grid_v1: (global_grid_v0 +j*dv);
-
- coord2f(u1, v1);
- coord2f(u2, v1);
- }
- endqstrip();
- }
- }
- else{
-
- for(i=vmin; i<vmax; i++){
- REAL v1 = (i==global_grid_nv)? global_grid_v1:(global_grid_v0 + i*dv);
- REAL v2 = ((i+1) == global_grid_nv)? global_grid_v1: (global_grid_v0+(i+1)*dv);
-
- bgnqstrip();
- for(j=umax; j>=umin; j--){
- REAL u1 = (j == global_grid_nu)? global_grid_u1: (global_grid_u0 +j*du);
- coord2f(u1, v2);
- coord2f(u1, v1);
- }
- endqstrip();
- }
- }
-#endif
-}
-else
-{
- switch(style) {
- default:
- case N_MESHFILL:
- glEvalMesh2((GLenum) GL_FILL, (GLint) umin, (GLint) umax,
- (GLint) vmin, (GLint) vmax);
- break;
- case N_MESHLINE:
- glEvalMesh2((GLenum) GL_LINE, (GLint) umin, (GLint) umax,
- (GLint) vmin, (GLint) vmax);
- break;
- case N_MESHPOINT:
- glEvalMesh2((GLenum) GL_POINT, (GLint) umin, (GLint) umax,
- (GLint) vmin, (GLint) vmax);
- break;
- }
- }
-
-#endif
-
-#ifdef STATISTICS
- STAT_num_of_quad_strips += (umax-umin)*(vmax-vmin);
-#endif
-}
-
-/*-------------------------------------------------------------------------
- * evalcoord2f - evaluate a point on a surface
- *-------------------------------------------------------------------------
- */
-void
-OpenGLSurfaceEvaluator::evalcoord2f(long, REAL u, REAL v)
-{
-
-
-#ifdef NO_EVALUATION
-return;
-#endif
-
-
- newtmeshvert(u, v);
-}
-
-/*-------------------------------------------------------------------------
- * evalpoint2i - evaluate a grid point
- *-------------------------------------------------------------------------
- */
-void
-OpenGLSurfaceEvaluator::evalpoint2i(long u, long v)
-{
-#ifdef NO_EVALUATION
-return;
-#endif
-
- newtmeshvert(u, v);
-}
-
-void
-OpenGLSurfaceEvaluator::point2i( long u, long v )
-{
-#ifdef NO_EVALUATION
-return;
-#else
-
-#ifdef USE_INTERNAL_EVAL
- inEvalPoint2( (int)u, (int)v);
-#else
-
-
-if(output_triangles)
-{
-
- REAL du, dv;
- REAL fu,fv;
- du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu;
- dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv;
- fu = (u==global_grid_nu)? global_grid_u1:(global_grid_u0 + u*du);
- fv = (v == global_grid_nv)? global_grid_v1: (global_grid_v0 +v*dv);
- coord2f(fu,fv);
-}
-else
- glEvalPoint2((GLint) u, (GLint) v);
-
-
-#endif
-
-#ifdef STATISTICS
- STAT_num_of_eval_vertices++;
-#endif
-
-#endif
-
-}
-
-void
-OpenGLSurfaceEvaluator::coord2f( REAL u, REAL v )
-{
-#ifdef NO_EVALUATION
-return;
-#else
-
-#ifdef USE_INTERNAL_EVAL
- inEvalCoord2f( u, v);
-#else
-
-
-if(output_triangles)
- bezierPatchMeshInsertUV(global_bpm, u,v);
-else
- glEvalCoord2f((GLfloat) u, (GLfloat) v);
-
-
-#endif
-
-
-#ifdef STATISTICS
- STAT_num_of_eval_vertices++;
-#endif
-
-#endif
-}
-
-void
-OpenGLSurfaceEvaluator::newtmeshvert( long u, long v )
-{
-#ifdef NO_EVALUATION
-return;
-#else
-
- if (tmeshing) {
-
- if (vcount == 2) {
- vertexCache[0]->invoke(this);
- vertexCache[1]->invoke(this);
- point2i( u, v);
-
- } else {
- vcount++;
- }
-
- vertexCache[which]->saveEvalPoint(u, v);
- which = 1 - which;
- } else {
- point2i( u, v);
- }
-#endif
-}
-
-void
-OpenGLSurfaceEvaluator::newtmeshvert( REAL u, REAL v )
-{
-#ifdef NO_EVALUATION
-return;
-#else
- if (tmeshing) {
-
-
- if (vcount == 2) {
- vertexCache[0]->invoke(this);
- vertexCache[1]->invoke(this);
- coord2f(u,v);
-
- } else {
- vcount++;
- }
-
- vertexCache[which]->saveEvalCoord(u, v);
- which = 1 - which;
- } else {
-
- coord2f( u, v);
- }
-#endif
-
-}
-
-#ifdef _WIN32
-void OpenGLSurfaceEvaluator::putCallBack(GLenum which, void (GLAPIENTRY *fn)() )
-#else
-void OpenGLSurfaceEvaluator::putCallBack(GLenum which, _GLUfuncptr fn )
-#endif
-{
- switch(which)
- {
- case GLU_NURBS_BEGIN:
- beginCallBackN = (void (GLAPIENTRY *) (GLenum)) fn;
- break;
- case GLU_NURBS_END:
- endCallBackN = (void (GLAPIENTRY *) (void)) fn;
- break;
- case GLU_NURBS_VERTEX:
- vertexCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn;
- break;
- case GLU_NURBS_NORMAL:
- normalCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn;
- break;
- case GLU_NURBS_COLOR:
- colorCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn;
- break;
- case GLU_NURBS_TEXTURE_COORD:
- texcoordCallBackN = (void (GLAPIENTRY *) (const GLfloat*)) fn;
- break;
- case GLU_NURBS_BEGIN_DATA:
- beginCallBackData = (void (GLAPIENTRY *) (GLenum, void*)) fn;
- break;
- case GLU_NURBS_END_DATA:
- endCallBackData = (void (GLAPIENTRY *) (void*)) fn;
- break;
- case GLU_NURBS_VERTEX_DATA:
- vertexCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn;
- break;
- case GLU_NURBS_NORMAL_DATA:
- normalCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn;
- break;
- case GLU_NURBS_COLOR_DATA:
- colorCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn;
- break;
- case GLU_NURBS_TEXTURE_COORD_DATA:
- texcoordCallBackData = (void (GLAPIENTRY *) (const GLfloat*, void*)) fn;
- break;
-
- }
-}
-
-
-void
-OpenGLSurfaceEvaluator::beginCallBack(GLenum which, void *data)
-{
- if(beginCallBackData)
- beginCallBackData(which, data);
- else if(beginCallBackN)
- beginCallBackN(which);
-}
-
-void
-OpenGLSurfaceEvaluator::endCallBack(void *data)
-{
- if(endCallBackData)
- endCallBackData(data);
- else if(endCallBackN)
- endCallBackN();
-}
-
-void
-OpenGLSurfaceEvaluator::vertexCallBack(const GLfloat *vert, void* data)
-{
- if(vertexCallBackData)
- vertexCallBackData(vert, data);
- else if(vertexCallBackN)
- vertexCallBackN(vert);
-}
-
-
-void
-OpenGLSurfaceEvaluator::normalCallBack(const GLfloat *normal, void* data)
-{
- if(normalCallBackData)
- normalCallBackData(normal, data);
- else if(normalCallBackN)
- normalCallBackN(normal);
-}
-
-void
-OpenGLSurfaceEvaluator::colorCallBack(const GLfloat *color, void* data)
-{
- if(colorCallBackData)
- colorCallBackData(color, data);
- else if(colorCallBackN)
- colorCallBackN(color);
-}
-
-void
-OpenGLSurfaceEvaluator::texcoordCallBack(const GLfloat *texcoord, void* data)
-{
- if(texcoordCallBackData)
- texcoordCallBackData(texcoord, data);
- else if(texcoordCallBackN)
- texcoordCallBackN(texcoord);
-}
-
-
-
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * glsurfeval.h
- *
- */
-
-#ifndef __gluglsurfeval_h_
-#define __gluglsurfeval_h_
-
-#include "basicsurfeval.h"
-#include "bezierPatchMesh.h" //in case output triangles
-#include <GL/gl.h>
-#include <GL/glu.h>
-
-class SurfaceMap;
-class OpenGLSurfaceEvaluator;
-class StoredVertex;
-
-#define TYPECOORD 1
-#define TYPEPOINT 2
-
-/* Cache up to 3 vertices from tmeshes */
-#define VERTEX_CACHE_SIZE 3
-
-/*for internal evaluator callback stuff*/
-#ifndef IN_MAX_BEZIER_ORDER
-#define IN_MAX_BEZIER_ORDER 40 /*XXX should be bigger than machine order*/
-#endif
-
-#ifndef IN_MAX_DIMENSION
-#define IN_MAX_DIMENSION 4
-#endif
-
-typedef struct surfEvalMachine{
- REAL uprime;//cached previusly evaluated uprime.
- REAL vprime;
- int k; /*the dimension*/
- REAL u1;
- REAL u2;
- int ustride;
- int uorder;
- REAL v1;
- REAL v2;
- int vstride;
- int vorder;
- REAL ctlPoints[IN_MAX_BEZIER_ORDER*IN_MAX_BEZIER_ORDER*IN_MAX_DIMENSION];
- REAL ucoeff[IN_MAX_BEZIER_ORDER]; /*cache the polynomial values*/
- REAL vcoeff[IN_MAX_BEZIER_ORDER];
- REAL ucoeffDeriv[IN_MAX_BEZIER_ORDER]; /*cache the polynomial derivatives*/
- REAL vcoeffDeriv[IN_MAX_BEZIER_ORDER];
-} surfEvalMachine;
-
-
-
-class StoredVertex {
-public:
- StoredVertex() { type = 0; coord[0] = 0; coord[1] = 0; point[0] = 0; point[1] = 0; }
- ~StoredVertex(void) {}
- void saveEvalCoord(REAL x, REAL y)
- {coord[0] = x; coord[1] = y; type = TYPECOORD; }
- void saveEvalPoint(long x, long y)
- {point[0] = x; point[1] = y; type = TYPEPOINT; }
- void invoke(OpenGLSurfaceEvaluator *eval);
-
-private:
- int type;
- REAL coord[2];
- long point[2];
-};
-
-class OpenGLSurfaceEvaluator : public BasicSurfaceEvaluator {
-public:
- OpenGLSurfaceEvaluator();
- virtual ~OpenGLSurfaceEvaluator( void );
- void polymode( long style );
- void range2f( long, REAL *, REAL * );
- void domain2f( REAL, REAL, REAL, REAL );
- void addMap( SurfaceMap * ) { }
-
- void enable( long );
- void disable( long );
- void bgnmap2f( long );
- void map2f( long, REAL, REAL, long, long,
- REAL, REAL, long, long, REAL * );
- void mapgrid2f( long, REAL, REAL, long, REAL, REAL );
- void mapmesh2f( long, long, long, long, long );
- void evalcoord2f( long, REAL, REAL );
- void evalpoint2i( long, long );
- void endmap2f( void );
-
- void bgnline( void );
- void endline( void );
- void bgnclosedline( void );
- void endclosedline( void );
- void bgntmesh( void );
- void swaptmesh( void );
- void endtmesh( void );
- void bgnqstrip( void );
- void endqstrip( void );
-
- void bgntfan( void );
- void endtfan( void );
- void evalUStrip(int n_upper, REAL v_upper, REAL* upper_val,
- int n_lower, REAL v_lower, REAL* lower_val);
- void evalVStrip(int n_left, REAL u_left, REAL* left_val,
- int n_right, REAL u_right, REAL* right_val);
-
- void coord2f( REAL, REAL );
- void point2i( long, long );
-
- void newtmeshvert( REAL, REAL );
- void newtmeshvert( long, long );
-
-#ifdef _WIN32
- void putCallBack(GLenum which, void (GLAPIENTRY *fn)() );
-#else
- void putCallBack(GLenum which, _GLUfuncptr fn );
-#endif
-
- int get_vertices_call_back()
- {
- return output_triangles;
- }
- void put_vertices_call_back(int flag)
- {
- output_triangles = flag;
- }
-
- void put_callback_auto_normal(int flag)
- {
- callback_auto_normal = flag;
- }
-
- int get_callback_auto_normal()
- {
- return callback_auto_normal;
- }
-
- void set_callback_userData(void* data)
- {
- userData = data;
- }
-
- /**************begin for LOD_eval_list***********/
- void LOD_eval_list(int level);
-
-
-
-
-private:
- StoredVertex *vertexCache[VERTEX_CACHE_SIZE];
- int tmeshing;
- int which;
- int vcount;
-
- GLint gl_polygon_mode[2];/*to save and restore so that
- *no side effect
- */
- bezierPatchMesh *global_bpm; //for output triangles
- int output_triangles; //true 1 or false 0
-
-
-
- void (GLAPIENTRY *beginCallBackN) (GLenum type);
- void (GLAPIENTRY *endCallBackN) (void);
- void (GLAPIENTRY *vertexCallBackN) (const GLfloat *vert);
- void (GLAPIENTRY *normalCallBackN) (const GLfloat *normal);
- void (GLAPIENTRY *colorCallBackN) (const GLfloat *color);
- void (GLAPIENTRY *texcoordCallBackN) (const GLfloat *texcoord);
-
- void (GLAPIENTRY *beginCallBackData) (GLenum type, void* data);
- void (GLAPIENTRY *endCallBackData) (void* data);
- void (GLAPIENTRY *vertexCallBackData) (const GLfloat *vert, void* data);
- void (GLAPIENTRY *normalCallBackData) (const GLfloat *normal, void* data);
- void (GLAPIENTRY *colorCallBackData) (const GLfloat *color, void* data);
- void (GLAPIENTRY *texcoordCallBackData) (const GLfloat *texcoord, void* data);
-
- void beginCallBack (GLenum type, void* data);
- void endCallBack (void* data);
- void vertexCallBack (const GLfloat *vert, void* data);
- void normalCallBack (const GLfloat *normal, void* data);
- void colorCallBack (const GLfloat *color, void* data);
- void texcoordCallBack (const GLfloat *texcoord, void* data);
-
-
- void* userData; //the opaque pointer for Data callback functions.
-
- /*LOD evaluation*/
- void LOD_triangle(REAL A[2], REAL B[2], REAL C[2],
- int level);
- void LOD_eval(int num_vert, REAL* verts, int type, int level);
-
- int LOD_eval_level; //set by LOD_eval_list()
-
- /*************begin for internal evaluators*****************/
-
- /*the following global variables are only defined in this file.
- *They are used to cache the precomputed Bezier polynomial values.
- *These calues may be used consecutively in which case we don't have
- *recompute these values again.
- */
- int global_uorder; /*store the uorder in the previous evaluation*/
- int global_vorder; /*store the vorder in the previous evaluation*/
- REAL global_uprime;
- REAL global_vprime;
- REAL global_vprime_BV;
- REAL global_uprime_BU;
- int global_uorder_BV; /*store the uorder in the previous evaluation*/
- int global_vorder_BV; /*store the vorder in the previous evaluation*/
- int global_uorder_BU; /*store the uorder in the previous evaluation*/
- int global_vorder_BU; /*store the vorder in the previous evaluation*/
-
- REAL global_ucoeff[IN_MAX_BEZIER_ORDER]; /*cache the polynomial values*/
- REAL global_vcoeff[IN_MAX_BEZIER_ORDER];
- REAL global_ucoeffDeriv[IN_MAX_BEZIER_ORDER]; /*cache the polynomial derivatives*/
- REAL global_vcoeffDeriv[IN_MAX_BEZIER_ORDER];
-
- REAL global_BV[IN_MAX_BEZIER_ORDER][IN_MAX_DIMENSION];
- REAL global_PBV[IN_MAX_BEZIER_ORDER][IN_MAX_DIMENSION];
- REAL global_BU[IN_MAX_BEZIER_ORDER][IN_MAX_DIMENSION];
- REAL global_PBU[IN_MAX_BEZIER_ORDER][IN_MAX_DIMENSION];
- REAL* global_baseData;
-
- int global_ev_k; /*the dimension*/
- REAL global_ev_u1;
- REAL global_ev_u2;
- int global_ev_ustride;
- int global_ev_uorder;
- REAL global_ev_v1;
- REAL global_ev_v2;
- int global_ev_vstride;
- int global_ev_vorder;
- REAL global_ev_ctlPoints[IN_MAX_BEZIER_ORDER*IN_MAX_BEZIER_ORDER*IN_MAX_DIMENSION];
-
- REAL global_grid_u0;
- REAL global_grid_u1;
- int global_grid_nu;
- REAL global_grid_v0;
- REAL global_grid_v1;
- int global_grid_nv;
-
-/*functions*/
- void inDoDomain2WithDerivs(int k, REAL u, REAL v,
- REAL u1, REAL u2, int uorder,
- REAL v1, REAL v2, int vorder,
- REAL *baseData,
- REAL *retPoint, REAL *retdu, REAL *retdv);
- void inPreEvaluate(int order, REAL vprime, REAL *coeff);
- void inPreEvaluateWithDeriv(int order, REAL vprime, REAL *coeff, REAL *coeffDeriv);
- void inComputeFirstPartials(REAL *p, REAL *pu, REAL *pv);
- void inComputeNormal2(REAL *pu, REAL *pv, REAL *n);
- void inDoEvalCoord2(REAL u, REAL v,
- REAL *retPoint, REAL *retNormal);
- void inDoEvalCoord2NOGE(REAL u, REAL v,
- REAL *retPoint, REAL *retNormal);
- void inMap2f(int k,
- REAL ulower,
- REAL uupper,
- int ustride,
- int uorder,
- REAL vlower,
- REAL vupper,
- int vstride,
- int vorder,
- REAL *ctlPoints);
-
- void inMapGrid2f(int nu, REAL u0, REAL u1,
- int nv, REAL v0, REAL v1);
-
- void inEvalMesh2(int lowU, int lowV, int highU, int highV);
- void inEvalPoint2(int i, int j);
- void inEvalCoord2f(REAL u, REAL v);
-
-void inEvalULine(int n_points, REAL v, REAL* u_vals,
- int stride, REAL ret_points[][3], REAL ret_normals[][3]);
-
-void inEvalVLine(int n_points, REAL u, REAL* v_vals,
- int stride, REAL ret_points[][3], REAL ret_normals[][3]);
-
-void inEvalUStrip(int n_upper, REAL v_upper, REAL* upper_val,
- int n_lower, REAL v_lower, REAL* lower_val
- );
-void inEvalVStrip(int n_left, REAL u_left, REAL* left_val, int n_right, REAL u_right, REAL* right_val);
-
-void inPreEvaluateBV(int k, int uorder, int vorder, REAL vprime, REAL *baseData);
-void inPreEvaluateBU(int k, int uorder, int vorder, REAL uprime, REAL *baseData);
-void inPreEvaluateBV_intfac(REAL v )
- {
- inPreEvaluateBV(global_ev_k, global_ev_uorder, global_ev_vorder, (v-global_ev_v1)/(global_ev_v2-global_ev_v1), global_ev_ctlPoints);
- }
-
-void inPreEvaluateBU_intfac(REAL u)
- {
- inPreEvaluateBU(global_ev_k, global_ev_uorder, global_ev_vorder, (u-global_ev_u1)/(global_ev_u2-global_ev_u1), global_ev_ctlPoints);
- }
-
-void inDoDomain2WithDerivsBV(int k, REAL u, REAL v,
- REAL u1, REAL u2, int uorder,
- REAL v1, REAL v2, int vorder,
- REAL *baseData,
- REAL *retPoint, REAL* retdu, REAL *retdv);
-
-void inDoDomain2WithDerivsBU(int k, REAL u, REAL v,
- REAL u1, REAL u2, int uorder,
- REAL v1, REAL v2, int vorder,
- REAL *baseData,
- REAL *retPoint, REAL* retdu, REAL *retdv);
-
-
-void inDoEvalCoord2NOGE_BV(REAL u, REAL v,
- REAL *retPoint, REAL *retNormal);
-
-void inDoEvalCoord2NOGE_BU(REAL u, REAL v,
- REAL *retPoint, REAL *retNormal);
-
-void inBPMEval(bezierPatchMesh* bpm);
-void inBPMListEval(bezierPatchMesh* list);
-
-/*-------------begin for surfEvalMachine -------------*/
-surfEvalMachine em_vertex;
-surfEvalMachine em_normal;
-surfEvalMachine em_color;
-surfEvalMachine em_texcoord;
-
-int auto_normal_flag; //whether to output normla or not in callback
- //determined by GL_AUTO_NORMAL and callback_auto_normal
-int callback_auto_normal; //GLU_CALLBACK_AUTO_NORMAL_EXT
-int vertex_flag;
-int normal_flag;
-int color_flag;
-int texcoord_flag;
-
-void inMap2fEM(int which, //0:vert,1:norm,2:color,3:tex
- int dimension,
- REAL ulower,
- REAL uupper,
- int ustride,
- int uorder,
- REAL vlower,
- REAL vupper,
- int vstride,
- int vorder,
- REAL *ctlPoints);
-
-void inDoDomain2WithDerivsEM(surfEvalMachine *em, REAL u, REAL v,
- REAL *retPoint, REAL *retdu, REAL *retdv);
-void inDoDomain2EM(surfEvalMachine *em, REAL u, REAL v,
- REAL *retPoint);
- void inDoEvalCoord2EM(REAL u, REAL v);
-
-void inBPMEvalEM(bezierPatchMesh* bpm);
-void inBPMListEvalEM(bezierPatchMesh* list);
-
-/*-------------end for surfEvalMachine -------------*/
-
-
- /*************end for internal evaluators*****************/
-
-};
-
-inline void StoredVertex::invoke(OpenGLSurfaceEvaluator *eval)
-{
- switch(type) {
- case TYPECOORD:
- eval->coord2f(coord[0], coord[1]);
- break;
- case TYPEPOINT:
- eval->point2i(point[0], point[1]);
- break;
- default:
- break;
- }
-}
-
-#endif /* __gluglsurfeval_h_ */
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "glcurveval.h"
-
-
-/*
- *compute the Bezier polynomials C[n,j](v) for all j at v with
- *return values stored in coeff[], where
- * C[n,j](v) = (n,j) * v^j * (1-v)^(n-j),
- * j=0,1,2,...,n.
- *order : n+1
- *vprime: v
- *coeff : coeff[j]=C[n,j](v), this array store the returned values.
- *The algorithm is a recursive scheme:
- * C[0,0]=1;
- * C[n,j](v) = (1-v)*C[n-1,j](v) + v*C[n-1,j-1](v), n>=1
- *This code is copied from opengl/soft/so_eval.c:PreEvaluate
- */
-void OpenGLCurveEvaluator::inPreEvaluate(int order, REAL vprime, REAL *coeff)
-{
- int i, j;
- REAL oldval, temp;
- REAL oneMinusvprime;
-
- /*
- * Minor optimization
- * Compute orders 1 and 2 outright, and set coeff[0], coeff[1] to
- * their i==1 loop values to avoid the initialization and the i==1 loop.
- */
- if (order == 1) {
- coeff[0] = 1.0;
- return;
- }
-
- oneMinusvprime = 1-vprime;
- coeff[0] = oneMinusvprime;
- coeff[1] = vprime;
- if (order == 2) return;
-
- for (i = 2; i < order; i++) {
- oldval = coeff[0] * vprime;
- coeff[0] = oneMinusvprime * coeff[0];
- for (j = 1; j < i; j++) {
- temp = oldval;
- oldval = coeff[j] * vprime;
- coeff[j] = temp + oneMinusvprime * coeff[j];
- }
- coeff[j] = oldval;
- }
-}
-
-void OpenGLCurveEvaluator::inMap1f(int which, //0: vert, 1: norm, 2: color, 3: tex
- int k, //dimension
- REAL ulower,
- REAL uupper,
- int ustride,
- int uorder,
- REAL *ctlpoints)
-{
- int i,x;
- curveEvalMachine *temp_em;
- switch(which){
- case 0: //vertex
- vertex_flag = 1;
- temp_em = &em_vertex;
- break;
- case 1: //normal
- normal_flag = 1;
- temp_em = &em_normal;
- break;
- case 2: //color
- color_flag = 1;
- temp_em = &em_color;
- break;
- default:
- texcoord_flag = 1;
- temp_em = &em_texcoord;
- break;
- }
-
- REAL *data = temp_em->ctlpoints;
- temp_em->uprime = -1; //initialized
- temp_em->k = k;
- temp_em->u1 = ulower;
- temp_em->u2 = uupper;
- temp_em->ustride = ustride;
- temp_em->uorder = uorder;
- /*copy the control points*/
- for(i=0; i<uorder; i++){
- for(x=0; x<k; x++){
- data[x] = ctlpoints[x];
- }
- ctlpoints += ustride;
- data += k;
- }
-}
-
-void OpenGLCurveEvaluator::inDoDomain1(curveEvalMachine *em, REAL u, REAL *retPoint)
-{
- int j, row;
- REAL the_uprime;
- REAL *data;
-
- if(em->u2 == em->u1)
- return;
- the_uprime = (u-em->u1) / (em->u2-em->u1);
- /*use already cached values if possible*/
- if(em->uprime != the_uprime){
- inPreEvaluate(em->uorder, the_uprime, em->ucoeff);
- em->uprime = the_uprime;
- }
-
- for(j=0; j<em->k; j++){
- data = em->ctlpoints+j;
- retPoint[j] = 0.0;
- for(row=0; row<em->uorder; row++)
- {
- retPoint[j] += em->ucoeff[row] * (*data);
- data += em->k;
- }
- }
-}
-
-void OpenGLCurveEvaluator::inDoEvalCoord1(REAL u)
-{
- REAL temp_vertex[4];
- REAL temp_normal[3];
- REAL temp_color[4];
- REAL temp_texcoord[4];
- if(texcoord_flag) //there is a texture map
- {
- inDoDomain1(&em_texcoord, u, temp_texcoord);
- texcoordCallBack(temp_texcoord, userData);
- }
-#ifdef DEBUG
-printf("color_flag = %i\n", color_flag);
-#endif
- if(color_flag) //there is a color map
- {
- inDoDomain1(&em_color, u, temp_color);
- colorCallBack(temp_color, userData);
- }
- if(normal_flag) //there is a normal map
- {
- inDoDomain1(&em_normal, u, temp_normal);
- normalCallBack(temp_normal, userData);
- }
- if(vertex_flag)
- {
- inDoDomain1(&em_vertex, u, temp_vertex);
- vertexCallBack(temp_vertex, userData);
- }
-}
-
-void OpenGLCurveEvaluator::inMapMesh1f(int umin, int umax)
-{
- REAL du, u;
- int i;
- if(global_grid_nu == 0)
- return; //no points to output
- du = (global_grid_u1 - global_grid_u0) / (REAL) global_grid_nu;
- bgnline();
- for(i=umin; i<= umax; i++){
- u = (i==global_grid_nu)? global_grid_u1: global_grid_u0 + i*du;
- inDoEvalCoord1(u);
- }
- endline();
-}
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include "gluos.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <GL/gl.h>
-#include <math.h>
-#include <assert.h>
-
-#include "glsurfeval.h"
-
-//extern int surfcount;
-
-//#define CRACK_TEST
-
-#define AVOID_ZERO_NORMAL
-
-#ifdef AVOID_ZERO_NORMAL
-#define myabs(x) ((x>0)? x: (-x))
-#define MYZERO 0.000001
-#define MYDELTA 0.001
-#endif
-
-//#define USE_LOD
-#ifdef USE_LOD
-//#define LOD_EVAL_COORD(u,v) inDoEvalCoord2EM(u,v)
-#define LOD_EVAL_COORD(u,v) glEvalCoord2f(u,v)
-
-static void LOD_interpolate(REAL A[2], REAL B[2], REAL C[2], int j, int k, int pow2_level,
- REAL& u, REAL& v)
-{
- REAL a,a1,b,b1;
-
- a = ((REAL) j) / ((REAL) pow2_level);
- a1 = 1-a;
-
- if(j != 0)
- {
- b = ((REAL) k) / ((REAL)j);
- b1 = 1-b;
- }
- REAL x,y,z;
- x = a1;
- if(j==0)
- {
- y=0; z=0;
- }
- else{
- y = b1*a;
- z = b *a;
- }
-
- u = x*A[0] + y*B[0] + z*C[0];
- v = x*A[1] + y*B[1] + z*C[1];
-}
-
-void OpenGLSurfaceEvaluator::LOD_triangle(REAL A[2], REAL B[2], REAL C[2],
- int level)
-{
- int k,j;
- int pow2_level;
- /*compute 2^level*/
- pow2_level = 1;
-
- for(j=0; j<level; j++)
- pow2_level *= 2;
- for(j=0; j<=pow2_level-1; j++)
- {
- REAL u,v;
-
-/* beginCallBack(GL_TRIANGLE_STRIP);*/
-glBegin(GL_TRIANGLE_STRIP);
- LOD_interpolate(A,B,C, j+1, j+1, pow2_level, u,v);
-#ifdef USE_LOD
- LOD_EVAL_COORD(u,v);
-// glEvalCoord2f(u,v);
-#else
- inDoEvalCoord2EM(u,v);
-#endif
-
- for(k=0; k<=j; k++)
- {
- LOD_interpolate(A,B,C,j,j-k,pow2_level, u,v);
-#ifdef USE_LOD
- LOD_EVAL_COORD(u,v);
-// glEvalCoord2f(u,v);
-#else
- inDoEvalCoord2EM(u,v);
-#endif
-
- LOD_interpolate(A,B,C,j+1,j-k,pow2_level, u,v);
-
-#ifdef USE_LOD
- LOD_EVAL_COORD(u,v);
-// glEvalCoord2f(u,v);
-#else
- inDoEvalCoord2EM(u,v);
-#endif
- }
-// endCallBack();
-glEnd();
- }
-}
-
-void OpenGLSurfaceEvaluator::LOD_eval(int num_vert, REAL* verts, int type,
- int level
- )
-{
- int i,k;
- switch(type){
- case GL_TRIANGLE_STRIP:
- case GL_QUAD_STRIP:
- for(i=2, k=4; i<=num_vert-2; i+=2, k+=4)
- {
- LOD_triangle(verts+k-4, verts+k-2, verts+k,
- level
- );
- LOD_triangle(verts+k-2, verts+k+2, verts+k,
- level
- );
- }
- if(num_vert % 2 ==1)
- {
- LOD_triangle(verts+2*(num_vert-3), verts+2*(num_vert-2), verts+2*(num_vert-1),
- level
- );
- }
- break;
- case GL_TRIANGLE_FAN:
- for(i=1, k=2; i<=num_vert-2; i++, k+=2)
- {
- LOD_triangle(verts,verts+k, verts+k+2,
- level
- );
- }
- break;
-
- default:
- fprintf(stderr, "typy not supported in LOD_\n");
- }
-}
-
-
-#endif //USE_LOD
-
-//#define GENERIC_TEST
-#ifdef GENERIC_TEST
-extern float xmin, xmax, ymin, ymax, zmin, zmax; /*bounding box*/
-extern int temp_signal;
-
-static void gTessVertexSphere(float u, float v, float temp_normal[3], float temp_vertex[3])
-{
- float r=2.0;
- float Ox = 0.5*(xmin+xmax);
- float Oy = 0.5*(ymin+ymax);
- float Oz = 0.5*(zmin+zmax);
- float nx = cos(v) * sin(u);
- float ny = sin(v) * sin(u);
- float nz = cos(u);
- float x= Ox+r * nx;
- float y= Oy+r * ny;
- float z= Oz+r * nz;
-
- temp_normal[0] = nx;
- temp_normal[1] = ny;
- temp_normal[2] = nz;
- temp_vertex[0] = x;
- temp_vertex[1] = y;
- temp_vertex[2] = z;
-
-// glNormal3f(nx,ny,nz);
-// glVertex3f(x,y,z);
-}
-
-static void gTessVertexCyl(float u, float v, float temp_normal[3], float temp_vertex[3])
-{
- float r=2.0;
- float Ox = 0.5*(xmin+xmax);
- float Oy = 0.5*(ymin+ymax);
- float Oz = 0.5*(zmin+zmax);
- float nx = cos(v);
- float ny = sin(v);
- float nz = 0;
- float x= Ox+r * nx;
- float y= Oy+r * ny;
- float z= Oz - 2*u;
-
- temp_normal[0] = nx;
- temp_normal[1] = ny;
- temp_normal[2] = nz;
- temp_vertex[0] = x;
- temp_vertex[1] = y;
- temp_vertex[2] = z;
-
-/*
- glNormal3f(nx,ny,nz);
- glVertex3f(x,y,z);
-*/
-}
-
-#endif //GENERIC_TEST
-
-void OpenGLSurfaceEvaluator::inBPMListEval(bezierPatchMesh* list)
-{
- bezierPatchMesh* temp;
- for(temp = list; temp != NULL; temp = temp->next)
- {
- inBPMEval(temp);
- }
-}
-
-void OpenGLSurfaceEvaluator::inBPMEval(bezierPatchMesh* bpm)
-{
- int i,j,k,l;
- float u,v;
-
- int ustride = bpm->bpatch->dimension * bpm->bpatch->vorder;
- int vstride = bpm->bpatch->dimension;
- inMap2f(
- (bpm->bpatch->dimension == 3)? GL_MAP2_VERTEX_3 : GL_MAP2_VERTEX_4,
- bpm->bpatch->umin,
- bpm->bpatch->umax,
- ustride,
- bpm->bpatch->uorder,
- bpm->bpatch->vmin,
- bpm->bpatch->vmax,
- vstride,
- bpm->bpatch->vorder,
- bpm->bpatch->ctlpoints);
-
- bpm->vertex_array = (float*) malloc(sizeof(float)* (bpm->index_UVarray/2) * 3+1); /*in case the origional dimenion is 4, then we need 4 space to pass to evaluator.*/
- assert(bpm->vertex_array);
- bpm->normal_array = (float*) malloc(sizeof(float)* (bpm->index_UVarray/2) * 3);
- assert(bpm->normal_array);
-#ifdef CRACK_TEST
-if( global_ev_u1 ==2 && global_ev_u2 == 3
- && global_ev_v1 ==2 && global_ev_v2 == 3)
-{
-REAL vertex[4];
-REAL normal[4];
-#ifdef DEBUG
-printf("***number 1\n");
-#endif
-
-beginCallBack(GL_QUAD_STRIP, NULL);
-inEvalCoord2f(3.0, 3.0);
-inEvalCoord2f(2.0, 3.0);
-inEvalCoord2f(3.0, 2.7);
-inEvalCoord2f(2.0, 2.7);
-inEvalCoord2f(3.0, 2.0);
-inEvalCoord2f(2.0, 2.0);
-endCallBack(NULL);
-
-
-beginCallBack(GL_TRIANGLE_STRIP, NULL);
-inEvalCoord2f(2.0, 3.0);
-inEvalCoord2f(2.0, 2.0);
-inEvalCoord2f(2.0, 2.7);
-endCallBack(NULL);
-
-}
-
-/*
-if( global_ev_u1 ==2 && global_ev_u2 == 3
- && global_ev_v1 ==1 && global_ev_v2 == 2)
-{
-#ifdef DEBUG
-printf("***number 2\n");
-#endif
-beginCallBack(GL_QUAD_STRIP);
-inEvalCoord2f(2.0, 2.0);
-inEvalCoord2f(2.0, 1.0);
-inEvalCoord2f(3.0, 2.0);
-inEvalCoord2f(3.0, 1.0);
-endCallBack();
-}
-*/
-if( global_ev_u1 ==1 && global_ev_u2 == 2
- && global_ev_v1 ==2 && global_ev_v2 == 3)
-{
-#ifdef DEBUG
-printf("***number 3\n");
-#endif
-beginCallBack(GL_QUAD_STRIP, NULL);
-inEvalCoord2f(2.0, 3.0);
-inEvalCoord2f(1.0, 3.0);
-inEvalCoord2f(2.0, 2.3);
-inEvalCoord2f(1.0, 2.3);
-inEvalCoord2f(2.0, 2.0);
-inEvalCoord2f(1.0, 2.0);
-endCallBack(NULL);
-
-beginCallBack(GL_TRIANGLE_STRIP, NULL);
-inEvalCoord2f(2.0, 2.3);
-inEvalCoord2f(2.0, 2.0);
-inEvalCoord2f(2.0, 3.0);
-endCallBack(NULL);
-
-}
-return;
-#endif
-
- k=0;
- l=0;
-
- for(i=0; i<bpm->index_length_array; i++)
- {
- beginCallBack(bpm->type_array[i], userData);
- for(j=0; j<bpm->length_array[i]; j++)
- {
- u = bpm->UVarray[k];
- v = bpm->UVarray[k+1];
- inDoEvalCoord2NOGE(u,v,
- bpm->vertex_array+l,
- bpm->normal_array+l);
-
- normalCallBack(bpm->normal_array+l, userData);
- vertexCallBack(bpm->vertex_array+l, userData);
-
- k += 2;
- l += 3;
- }
- endCallBack(userData);
- }
-}
-
-void OpenGLSurfaceEvaluator::inEvalPoint2(int i, int j)
-{
- REAL du, dv;
- REAL point[4];
- REAL normal[3];
- REAL u,v;
- du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu;
- dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv;
- u = (i==global_grid_nu)? global_grid_u1:(global_grid_u0 + i*du);
- v = (j == global_grid_nv)? global_grid_v1: (global_grid_v0 +j*dv);
- inDoEvalCoord2(u,v,point,normal);
-}
-
-void OpenGLSurfaceEvaluator::inEvalCoord2f(REAL u, REAL v)
-{
-
- REAL point[4];
- REAL normal[3];
- inDoEvalCoord2(u,v,point, normal);
-}
-
-
-
-/*define a grid. store the values into the global variabls:
- * global_grid_*
- *These values will be used later by evaluating functions
- */
-void OpenGLSurfaceEvaluator::inMapGrid2f(int nu, REAL u0, REAL u1,
- int nv, REAL v0, REAL v1)
-{
- global_grid_u0 = u0;
- global_grid_u1 = u1;
- global_grid_nu = nu;
- global_grid_v0 = v0;
- global_grid_v1 = v1;
- global_grid_nv = nv;
-}
-
-void OpenGLSurfaceEvaluator::inEvalMesh2(int lowU, int lowV, int highU, int highV)
-{
- REAL du, dv;
- int i,j;
- REAL point[4];
- REAL normal[3];
- if(global_grid_nu == 0 || global_grid_nv == 0)
- return; /*no points need to be output*/
- du = (global_grid_u1 - global_grid_u0) / (REAL)global_grid_nu;
- dv = (global_grid_v1 - global_grid_v0) / (REAL)global_grid_nv;
-
- if(global_grid_nu >= global_grid_nv){
- for(i=lowU; i<highU; i++){
- REAL u1 = (i==global_grid_nu)? global_grid_u1:(global_grid_u0 + i*du);
- REAL u2 = ((i+1) == global_grid_nu)? global_grid_u1: (global_grid_u0+(i+1)*du);
-
- bgnqstrip();
- for(j=highV; j>=lowV; j--){
- REAL v1 = (j == global_grid_nv)? global_grid_v1: (global_grid_v0 +j*dv);
-
- inDoEvalCoord2(u1, v1, point, normal);
- inDoEvalCoord2(u2, v1, point, normal);
- }
- endqstrip();
- }
- }
-
- else{
- for(i=lowV; i<highV; i++){
- REAL v1 = (i==global_grid_nv)? global_grid_v1:(global_grid_v0 + i*dv);
- REAL v2 = ((i+1) == global_grid_nv)? global_grid_v1: (global_grid_v0+(i+1)*dv);
-
- bgnqstrip();
- for(j=highU; j>=lowU; j--){
- REAL u1 = (j == global_grid_nu)? global_grid_u1: (global_grid_u0 +j*du);
- inDoEvalCoord2(u1, v2, point, normal);
- inDoEvalCoord2(u1, v1, point, normal);
- }
- endqstrip();
- }
- }
-
-}
-
-void OpenGLSurfaceEvaluator::inMap2f(int k,
- REAL ulower,
- REAL uupper,
- int ustride,
- int uorder,
- REAL vlower,
- REAL vupper,
- int vstride,
- int vorder,
- REAL *ctlPoints)
-{
- int i,j,x;
- REAL *data = global_ev_ctlPoints;
-
-
-
- if(k == GL_MAP2_VERTEX_3) k=3;
- else if (k==GL_MAP2_VERTEX_4) k =4;
- else {
- printf("error in inMap2f, maptype=%i is wrong, k,map is not updated\n", k);
- return;
- }
-
- global_ev_k = k;
- global_ev_u1 = ulower;
- global_ev_u2 = uupper;
- global_ev_ustride = ustride;
- global_ev_uorder = uorder;
- global_ev_v1 = vlower;
- global_ev_v2 = vupper;
- global_ev_vstride = vstride;
- global_ev_vorder = vorder;
-
- /*copy the contrl points from ctlPoints to global_ev_ctlPoints*/
- for (i=0; i<uorder; i++) {
- for (j=0; j<vorder; j++) {
- for (x=0; x<k; x++) {
- data[x] = ctlPoints[x];
- }
- ctlPoints += vstride;
- data += k;
- }
- ctlPoints += ustride - vstride * vorder;
- }
-
-}
-
-
-/*
- *given a point p with homegeneous coordiante (x,y,z,w),
- *let pu(x,y,z,w) be its partial derivative vector with
- *respect to u
- *and pv(x,y,z,w) be its partial derivative vector with repect to v.
- *This function returns the partial derivative vectors of the
- *inhomegensous coordinates, i.e.,
- * (x/w, y/w, z/w) with respect to u and v.
- */
-void OpenGLSurfaceEvaluator::inComputeFirstPartials(REAL *p, REAL *pu, REAL *pv)
-{
- pu[0] = pu[0]*p[3] - pu[3]*p[0];
- pu[1] = pu[1]*p[3] - pu[3]*p[1];
- pu[2] = pu[2]*p[3] - pu[3]*p[2];
-
- pv[0] = pv[0]*p[3] - pv[3]*p[0];
- pv[1] = pv[1]*p[3] - pv[3]*p[1];
- pv[2] = pv[2]*p[3] - pv[3]*p[2];
-}
-
-/*compute the cross product of pu and pv and normalize.
- *the normal is returned in retNormal
- * pu: dimension 3
- * pv: dimension 3
- * n: return normal, of dimension 3
- */
-void OpenGLSurfaceEvaluator::inComputeNormal2(REAL *pu, REAL *pv, REAL *n)
-{
- REAL mag;
-
- n[0] = pu[1]*pv[2] - pu[2]*pv[1];
- n[1] = pu[2]*pv[0] - pu[0]*pv[2];
- n[2] = pu[0]*pv[1] - pu[1]*pv[0];
-
- mag = sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
-
- if (mag > 0.0) {
- n[0] /= mag;
- n[1] /= mag;
- n[2] /= mag;
- }
-}
-
-
-
-/*Compute point and normal
- *see the head of inDoDomain2WithDerivs
- *for the meaning of the arguments
- */
-void OpenGLSurfaceEvaluator::inDoEvalCoord2(REAL u, REAL v,
- REAL *retPoint, REAL *retNormal)
-{
-
- REAL du[4];
- REAL dv[4];
-
-
- assert(global_ev_k>=3 && global_ev_k <= 4);
- /*compute homegeneous point and partial derivatives*/
- inDoDomain2WithDerivs(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv);
-
-#ifdef AVOID_ZERO_NORMAL
-
- if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
- {
-
- REAL tempdu[4];
- REAL tempdata[4];
- REAL u1 = global_ev_u1;
- REAL u2 = global_ev_u2;
- if(u-MYDELTA*(u2-u1) < u1)
- u = u+ MYDELTA*(u2-u1);
- else
- u = u-MYDELTA*(u2-u1);
- inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, tempdu, dv);
- }
- if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
- {
- REAL tempdv[4];
- REAL tempdata[4];
- REAL v1 = global_ev_v1;
- REAL v2 = global_ev_v2;
- if(v-MYDELTA*(v2-v1) < v1)
- v = v+ MYDELTA*(v2-v1);
- else
- v = v-MYDELTA*(v2-v1);
- inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, du, tempdv);
- }
-#endif
-
-
- /*compute normal*/
- switch(global_ev_k){
- case 3:
- inComputeNormal2(du, dv, retNormal);
-
- break;
- case 4:
- inComputeFirstPartials(retPoint, du, dv);
- inComputeNormal2(du, dv, retNormal);
- /*transform the homegeneous coordinate of retPoint into inhomogenous one*/
- retPoint[0] /= retPoint[3];
- retPoint[1] /= retPoint[3];
- retPoint[2] /= retPoint[3];
- break;
- }
- /*output this vertex*/
-/* inMeshStreamInsert(global_ms, retPoint, retNormal);*/
-
-
-
- glNormal3fv(retNormal);
- glVertex3fv(retPoint);
-
-
-
-
- #ifdef DEBUG
- printf("vertex(%f,%f,%f)\n", retPoint[0],retPoint[1],retPoint[2]);
- #endif
-
-
-
-}
-
-/*Compute point and normal
- *see the head of inDoDomain2WithDerivs
- *for the meaning of the arguments
- */
-void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE_BU(REAL u, REAL v,
- REAL *retPoint, REAL *retNormal)
-{
-
- REAL du[4];
- REAL dv[4];
-
-
- assert(global_ev_k>=3 && global_ev_k <= 4);
- /*compute homegeneous point and partial derivatives*/
-// inPreEvaluateBU(global_ev_k, global_ev_uorder, global_ev_vorder, (u-global_ev_u1)/(global_ev_u2-global_ev_u1), global_ev_ctlPoints);
- inDoDomain2WithDerivsBU(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv);
-
-
-#ifdef AVOID_ZERO_NORMAL
-
- if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
- {
-
- REAL tempdu[4];
- REAL tempdata[4];
- REAL u1 = global_ev_u1;
- REAL u2 = global_ev_u2;
- if(u-MYDELTA*(u2-u1) < u1)
- u = u+ MYDELTA*(u2-u1);
- else
- u = u-MYDELTA*(u2-u1);
- inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, tempdu, dv);
- }
- if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
- {
- REAL tempdv[4];
- REAL tempdata[4];
- REAL v1 = global_ev_v1;
- REAL v2 = global_ev_v2;
- if(v-MYDELTA*(v2-v1) < v1)
- v = v+ MYDELTA*(v2-v1);
- else
- v = v-MYDELTA*(v2-v1);
- inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, du, tempdv);
- }
-#endif
-
- /*compute normal*/
- switch(global_ev_k){
- case 3:
- inComputeNormal2(du, dv, retNormal);
- break;
- case 4:
- inComputeFirstPartials(retPoint, du, dv);
- inComputeNormal2(du, dv, retNormal);
- /*transform the homegeneous coordinate of retPoint into inhomogenous one*/
- retPoint[0] /= retPoint[3];
- retPoint[1] /= retPoint[3];
- retPoint[2] /= retPoint[3];
- break;
- }
-}
-
-/*Compute point and normal
- *see the head of inDoDomain2WithDerivs
- *for the meaning of the arguments
- */
-void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE_BV(REAL u, REAL v,
- REAL *retPoint, REAL *retNormal)
-{
-
- REAL du[4];
- REAL dv[4];
-
-
- assert(global_ev_k>=3 && global_ev_k <= 4);
- /*compute homegeneous point and partial derivatives*/
-// inPreEvaluateBV(global_ev_k, global_ev_uorder, global_ev_vorder, (v-global_ev_v1)/(global_ev_v2-global_ev_v1), global_ev_ctlPoints);
-
- inDoDomain2WithDerivsBV(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv);
-
-
-#ifdef AVOID_ZERO_NORMAL
-
- if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
- {
-
- REAL tempdu[4];
- REAL tempdata[4];
- REAL u1 = global_ev_u1;
- REAL u2 = global_ev_u2;
- if(u-MYDELTA*(u2-u1) < u1)
- u = u+ MYDELTA*(u2-u1);
- else
- u = u-MYDELTA*(u2-u1);
- inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, tempdu, dv);
- }
- if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
- {
- REAL tempdv[4];
- REAL tempdata[4];
- REAL v1 = global_ev_v1;
- REAL v2 = global_ev_v2;
- if(v-MYDELTA*(v2-v1) < v1)
- v = v+ MYDELTA*(v2-v1);
- else
- v = v-MYDELTA*(v2-v1);
- inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, du, tempdv);
- }
-#endif
-
- /*compute normal*/
- switch(global_ev_k){
- case 3:
- inComputeNormal2(du, dv, retNormal);
- break;
- case 4:
- inComputeFirstPartials(retPoint, du, dv);
- inComputeNormal2(du, dv, retNormal);
- /*transform the homegeneous coordinate of retPoint into inhomogenous one*/
- retPoint[0] /= retPoint[3];
- retPoint[1] /= retPoint[3];
- retPoint[2] /= retPoint[3];
- break;
- }
-}
-
-
-/*Compute point and normal
- *see the head of inDoDomain2WithDerivs
- *for the meaning of the arguments
- */
-void OpenGLSurfaceEvaluator::inDoEvalCoord2NOGE(REAL u, REAL v,
- REAL *retPoint, REAL *retNormal)
-{
-
- REAL du[4];
- REAL dv[4];
-
-
- assert(global_ev_k>=3 && global_ev_k <= 4);
- /*compute homegeneous point and partial derivatives*/
- inDoDomain2WithDerivs(global_ev_k, u, v, global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, retPoint, du, dv);
-
-
-#ifdef AVOID_ZERO_NORMAL
-
- if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
- {
-
- REAL tempdu[4];
- REAL tempdata[4];
- REAL u1 = global_ev_u1;
- REAL u2 = global_ev_u2;
- if(u-MYDELTA*(u2-u1) < u1)
- u = u+ MYDELTA*(u2-u1);
- else
- u = u-MYDELTA*(u2-u1);
- inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, tempdu, dv);
- }
- if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
- {
- REAL tempdv[4];
- REAL tempdata[4];
- REAL v1 = global_ev_v1;
- REAL v2 = global_ev_v2;
- if(v-MYDELTA*(v2-v1) < v1)
- v = v+ MYDELTA*(v2-v1);
- else
- v = v-MYDELTA*(v2-v1);
- inDoDomain2WithDerivs(global_ev_k, u,v,global_ev_u1, global_ev_u2, global_ev_uorder, global_ev_v1, global_ev_v2, global_ev_vorder, global_ev_ctlPoints, tempdata, du, tempdv);
- }
-#endif
-
- /*compute normal*/
- switch(global_ev_k){
- case 3:
- inComputeNormal2(du, dv, retNormal);
- break;
- case 4:
- inComputeFirstPartials(retPoint, du, dv);
- inComputeNormal2(du, dv, retNormal);
- /*transform the homegeneous coordinate of retPoint into inhomogenous one*/
- retPoint[0] /= retPoint[3];
- retPoint[1] /= retPoint[3];
- retPoint[2] /= retPoint[3];
- break;
- }
-// glNormal3fv(retNormal);
-// glVertex3fv(retPoint);
-}
-
-void OpenGLSurfaceEvaluator::inPreEvaluateBV(int k, int uorder, int vorder, REAL vprime, REAL *baseData)
-{
- int j,row,col;
- REAL p, pdv;
- REAL *data;
-
- if(global_vprime != vprime || global_vorder != vorder) {
- inPreEvaluateWithDeriv(vorder, vprime, global_vcoeff, global_vcoeffDeriv);
- global_vprime = vprime;
- global_vorder = vorder;
- }
-
- for(j=0; j<k; j++){
- data = baseData+j;
- for(row=0; row<uorder; row++){
- p = global_vcoeff[0] * (*data);
- pdv = global_vcoeffDeriv[0] * (*data);
- data += k;
- for(col = 1; col < vorder; col++){
- p += global_vcoeff[col] * (*data);
- pdv += global_vcoeffDeriv[col] * (*data);
- data += k;
- }
- global_BV[row][j] = p;
- global_PBV[row][j] = pdv;
- }
- }
-}
-
-void OpenGLSurfaceEvaluator::inPreEvaluateBU(int k, int uorder, int vorder, REAL uprime, REAL *baseData)
-{
- int j,row,col;
- REAL p, pdu;
- REAL *data;
-
- if(global_uprime != uprime || global_uorder != uorder) {
- inPreEvaluateWithDeriv(uorder, uprime, global_ucoeff, global_ucoeffDeriv);
- global_uprime = uprime;
- global_uorder = uorder;
- }
-
- for(j=0; j<k; j++){
- data = baseData+j;
- for(col=0; col<vorder; col++){
- data = baseData+j + k*col;
- p = global_ucoeff[0] * (*data);
- pdu = global_ucoeffDeriv[0] * (*data);
- data += k*uorder;
- for(row = 1; row < uorder; row++){
- p += global_ucoeff[row] * (*data);
- pdu += global_ucoeffDeriv[row] * (*data);
- data += k * uorder;
- }
- global_BU[col][j] = p;
- global_PBU[col][j] = pdu;
- }
- }
-}
-
-void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsBU(int k, REAL u, REAL v,
- REAL u1, REAL u2, int uorder,
- REAL v1, REAL v2, int vorder,
- REAL *baseData,
- REAL *retPoint, REAL* retdu, REAL *retdv)
-{
- int j, col;
-
- REAL vprime;
-
-
- if((u2 == u1) || (v2 == v1))
- return;
-
- vprime = (v - v1) / (v2 - v1);
-
-
- if(global_vprime != vprime || global_vorder != vorder) {
- inPreEvaluateWithDeriv(vorder, vprime, global_vcoeff, global_vcoeffDeriv);
- global_vprime = vprime;
- global_vorder = vorder;
- }
-
-
- for(j=0; j<k; j++)
- {
- retPoint[j] = retdu[j] = retdv[j] = 0.0;
- for (col = 0; col < vorder; col++) {
- retPoint[j] += global_BU[col][j] * global_vcoeff[col];
- retdu[j] += global_PBU[col][j] * global_vcoeff[col];
- retdv[j] += global_BU[col][j] * global_vcoeffDeriv[col];
- }
- }
-}
-
-void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsBV(int k, REAL u, REAL v,
- REAL u1, REAL u2, int uorder,
- REAL v1, REAL v2, int vorder,
- REAL *baseData,
- REAL *retPoint, REAL* retdu, REAL *retdv)
-{
- int j, row;
- REAL uprime;
-
-
- if((u2 == u1) || (v2 == v1))
- return;
- uprime = (u - u1) / (u2 - u1);
-
-
- if(global_uprime != uprime || global_uorder != uorder) {
- inPreEvaluateWithDeriv(uorder, uprime, global_ucoeff, global_ucoeffDeriv);
- global_uprime = uprime;
- global_uorder = uorder;
- }
-
-
- for(j=0; j<k; j++)
- {
- retPoint[j] = retdu[j] = retdv[j] = 0.0;
- for (row = 0; row < uorder; row++) {
- retPoint[j] += global_BV[row][j] * global_ucoeff[row];
- retdu[j] += global_BV[row][j] * global_ucoeffDeriv[row];
- retdv[j] += global_PBV[row][j] * global_ucoeff[row];
- }
- }
-}
-
-
-/*
- *given a Bezier surface, and parameter (u,v), compute the point in the object space,
- *and the normal
- *k: the dimension of the object space: usually 2,3,or 4.
- *u,v: the paramter pair.
- *u1,u2,uorder: the Bezier polynomial of u coord is defined on [u1,u2] with order uorder.
- *v1,v2,vorder: the Bezier polynomial of v coord is defined on [v1,v2] with order vorder.
- *baseData: contrl points. arranged as: (u,v,k).
- *retPoint: the computed point (one point) with dimension k.
- *retdu: the computed partial derivative with respect to u.
- *retdv: the computed partial derivative with respect to v.
- */
-void OpenGLSurfaceEvaluator::inDoDomain2WithDerivs(int k, REAL u, REAL v,
- REAL u1, REAL u2, int uorder,
- REAL v1, REAL v2, int vorder,
- REAL *baseData,
- REAL *retPoint, REAL *retdu, REAL *retdv)
-{
- int j, row, col;
- REAL uprime;
- REAL vprime;
- REAL p;
- REAL pdv;
- REAL *data;
-
- if((u2 == u1) || (v2 == v1))
- return;
- uprime = (u - u1) / (u2 - u1);
- vprime = (v - v1) / (v2 - v1);
-
- /* Compute coefficients for values and derivs */
-
- /* Use already cached values if possible */
- if(global_uprime != uprime || global_uorder != uorder) {
- inPreEvaluateWithDeriv(uorder, uprime, global_ucoeff, global_ucoeffDeriv);
- global_uorder = uorder;
- global_uprime = uprime;
- }
- if (global_vprime != vprime ||
- global_vorder != vorder) {
- inPreEvaluateWithDeriv(vorder, vprime, global_vcoeff, global_vcoeffDeriv);
- global_vorder = vorder;
- global_vprime = vprime;
- }
-
- for (j = 0; j < k; j++) {
- data=baseData+j;
- retPoint[j] = retdu[j] = retdv[j] = 0.0;
- for (row = 0; row < uorder; row++) {
- /*
- ** Minor optimization.
- ** The col == 0 part of the loop is extracted so we don't
- ** have to initialize p and pdv to 0.
- */
- p = global_vcoeff[0] * (*data);
- pdv = global_vcoeffDeriv[0] * (*data);
- data += k;
- for (col = 1; col < vorder; col++) {
- /* Incrementally build up p, pdv value */
- p += global_vcoeff[col] * (*data);
- pdv += global_vcoeffDeriv[col] * (*data);
- data += k;
- }
- /* Use p, pdv value to incrementally add up r, du, dv */
- retPoint[j] += global_ucoeff[row] * p;
- retdu[j] += global_ucoeffDeriv[row] * p;
- retdv[j] += global_ucoeff[row] * pdv;
- }
- }
-}
-
-
-/*
- *compute the Bezier polynomials C[n,j](v) for all j at v with
- *return values stored in coeff[], where
- * C[n,j](v) = (n,j) * v^j * (1-v)^(n-j),
- * j=0,1,2,...,n.
- *order : n+1
- *vprime: v
- *coeff : coeff[j]=C[n,j](v), this array store the returned values.
- *The algorithm is a recursive scheme:
- * C[0,0]=1;
- * C[n,j](v) = (1-v)*C[n-1,j](v) + v*C[n-1,j-1](v), n>=1
- *This code is copied from opengl/soft/so_eval.c:PreEvaluate
- */
-void OpenGLSurfaceEvaluator::inPreEvaluate(int order, REAL vprime, REAL *coeff)
-{
- int i, j;
- REAL oldval, temp;
- REAL oneMinusvprime;
-
- /*
- * Minor optimization
- * Compute orders 1 and 2 outright, and set coeff[0], coeff[1] to
- * their i==1 loop values to avoid the initialization and the i==1 loop.
- */
- if (order == 1) {
- coeff[0] = 1.0;
- return;
- }
-
- oneMinusvprime = 1-vprime;
- coeff[0] = oneMinusvprime;
- coeff[1] = vprime;
- if (order == 2) return;
-
- for (i = 2; i < order; i++) {
- oldval = coeff[0] * vprime;
- coeff[0] = oneMinusvprime * coeff[0];
- for (j = 1; j < i; j++) {
- temp = oldval;
- oldval = coeff[j] * vprime;
- coeff[j] = temp + oneMinusvprime * coeff[j];
- }
- coeff[j] = oldval;
- }
-}
-
-/*
- *compute the Bezier polynomials C[n,j](v) and derivatives for all j at v with
- *return values stored in coeff[] and coeffDeriv[].
- *see the head of function inPreEvaluate for the definition of C[n,j](v)
- *and how to compute the values.
- *The algorithm to compute the derivative is:
- * dC[0,0](v) = 0.
- * dC[n,j](v) = n*(dC[n-1,j-1](v) - dC[n-1,j](v)).
- *
- *This code is copied from opengl/soft/so_eval.c:PreEvaluateWidthDeriv
- */
-void OpenGLSurfaceEvaluator::inPreEvaluateWithDeriv(int order, REAL vprime,
- REAL *coeff, REAL *coeffDeriv)
-{
- int i, j;
- REAL oldval, temp;
- REAL oneMinusvprime;
-
- oneMinusvprime = 1-vprime;
- /*
- * Minor optimization
- * Compute orders 1 and 2 outright, and set coeff[0], coeff[1] to
- * their i==1 loop values to avoid the initialization and the i==1 loop.
- */
- if (order == 1) {
- coeff[0] = 1.0;
- coeffDeriv[0] = 0.0;
- return;
- } else if (order == 2) {
- coeffDeriv[0] = -1.0;
- coeffDeriv[1] = 1.0;
- coeff[0] = oneMinusvprime;
- coeff[1] = vprime;
- return;
- }
- coeff[0] = oneMinusvprime;
- coeff[1] = vprime;
- for (i = 2; i < order - 1; i++) {
- oldval = coeff[0] * vprime;
- coeff[0] = oneMinusvprime * coeff[0];
- for (j = 1; j < i; j++) {
- temp = oldval;
- oldval = coeff[j] * vprime;
- coeff[j] = temp + oneMinusvprime * coeff[j];
- }
- coeff[j] = oldval;
- }
- coeffDeriv[0] = -coeff[0];
- /*
- ** Minor optimization:
- ** Would make this a "for (j=1; j<order-1; j++)" loop, but it is always
- ** executed at least once, so this is more efficient.
- */
- j=1;
- do {
- coeffDeriv[j] = coeff[j-1] - coeff[j];
- j++;
- } while (j < order - 1);
- coeffDeriv[j] = coeff[j-1];
-
- oldval = coeff[0] * vprime;
- coeff[0] = oneMinusvprime * coeff[0];
- for (j = 1; j < i; j++) {
- temp = oldval;
- oldval = coeff[j] * vprime;
- coeff[j] = temp + oneMinusvprime * coeff[j];
- }
- coeff[j] = oldval;
-}
-
-void OpenGLSurfaceEvaluator::inEvalULine(int n_points, REAL v, REAL* u_vals,
- int stride, REAL ret_points[][3], REAL ret_normals[][3])
-{
- int i,k;
- REAL temp[4];
-inPreEvaluateBV_intfac(v);
-
- for(i=0,k=0; i<n_points; i++, k += stride)
- {
- inDoEvalCoord2NOGE_BV(u_vals[k],v,temp, ret_normals[i]);
-
- ret_points[i][0] = temp[0];
- ret_points[i][1] = temp[1];
- ret_points[i][2] = temp[2];
-
- }
-
-}
-
-void OpenGLSurfaceEvaluator::inEvalVLine(int n_points, REAL u, REAL* v_vals,
- int stride, REAL ret_points[][3], REAL ret_normals[][3])
-{
- int i,k;
- REAL temp[4];
-inPreEvaluateBU_intfac(u);
- for(i=0,k=0; i<n_points; i++, k += stride)
- {
- inDoEvalCoord2NOGE_BU(u, v_vals[k], temp, ret_normals[i]);
- ret_points[i][0] = temp[0];
- ret_points[i][1] = temp[1];
- ret_points[i][2] = temp[2];
- }
-}
-
-
-/*triangulate a strip bounded by two lines which are parallel to U-axis
- *upperVerts: the verteces on the upper line
- *lowerVertx: the verteces on the lower line
- *n_upper >=1
- *n_lower >=1
- */
-void OpenGLSurfaceEvaluator::inEvalUStrip(int n_upper, REAL v_upper, REAL* upper_val, int n_lower, REAL v_lower, REAL* lower_val)
-{
- int i,j,k,l;
- REAL leftMostV[2];
- typedef REAL REAL3[3];
-
- REAL3* upperXYZ = (REAL3*) malloc(sizeof(REAL3)*n_upper);
- assert(upperXYZ);
- REAL3* upperNormal = (REAL3*) malloc(sizeof(REAL3) * n_upper);
- assert(upperNormal);
- REAL3* lowerXYZ = (REAL3*) malloc(sizeof(REAL3)*n_lower);
- assert(lowerXYZ);
- REAL3* lowerNormal = (REAL3*) malloc(sizeof(REAL3) * n_lower);
- assert(lowerNormal);
-
- inEvalULine(n_upper, v_upper, upper_val, 1, upperXYZ, upperNormal);
- inEvalULine(n_lower, v_lower, lower_val, 1, lowerXYZ, lowerNormal);
-
-
-
- REAL* leftMostXYZ;
- REAL* leftMostNormal;
-
- /*
- *the algorithm works by scanning from left to right.
- *leftMostV: the left most of the remaining verteces (on both upper and lower).
- * it could an element of upperVerts or lowerVerts.
- *i: upperVerts[i] is the first vertex to the right of leftMostV on upper line *j: lowerVerts[j] is the first vertex to the right of leftMostV on lower line */
-
- /*initialize i,j,and leftMostV
- */
- if(upper_val[0] <= lower_val[0])
- {
- i=1;
- j=0;
-
- leftMostV[0] = upper_val[0];
- leftMostV[1] = v_upper;
- leftMostXYZ = upperXYZ[0];
- leftMostNormal = upperNormal[0];
- }
- else
- {
- i=0;
- j=1;
-
- leftMostV[0] = lower_val[0];
- leftMostV[1] = v_lower;
-
- leftMostXYZ = lowerXYZ[0];
- leftMostNormal = lowerNormal[0];
- }
-
- /*the main loop.
- *the invariance is that:
- *at the beginning of each loop, the meaning of i,j,and leftMostV are
- *maintained
- */
- while(1)
- {
- if(i >= n_upper) /*case1: no more in upper*/
- {
- if(j<n_lower-1) /*at least two vertices in lower*/
- {
- bgntfan();
- glNormal3fv(leftMostNormal);
- glVertex3fv(leftMostXYZ);
-
- while(j<n_lower){
- glNormal3fv(lowerNormal[j]);
- glVertex3fv(lowerXYZ[j]);
- j++;
-
- }
- endtfan();
- }
- break; /*exit the main loop*/
- }
- else if(j>= n_lower) /*case2: no more in lower*/
- {
- if(i<n_upper-1) /*at least two vertices in upper*/
- {
- bgntfan();
- glNormal3fv(leftMostNormal);
- glVertex3fv(leftMostXYZ);
-
- for(k=n_upper-1; k>=i; k--) /*reverse order for two-side lighting*/
- {
- glNormal3fv(upperNormal[k]);
- glVertex3fv(upperXYZ[k]);
- }
-
- endtfan();
- }
- break; /*exit the main loop*/
- }
- else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output*/
- {
- if(upper_val[i] <= lower_val[j])
- {
- bgntfan();
-
- glNormal3fv(lowerNormal[j]);
- glVertex3fv(lowerXYZ[j]);
-
- /*find the last k>=i such that
- *upperverts[k][0] <= lowerverts[j][0]
- */
- k=i;
-
- while(k<n_upper)
- {
- if(upper_val[k] > lower_val[j])
- break;
- k++;
-
- }
- k--;
-
-
- for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/
- {
- glNormal3fv(upperNormal[l]);
- glVertex3fv(upperXYZ[l]);
-
- }
- glNormal3fv(leftMostNormal);
- glVertex3fv(leftMostXYZ);
-
- endtfan();
-
- /*update i and leftMostV for next loop
- */
- i = k+1;
-
- leftMostV[0] = upper_val[k];
- leftMostV[1] = v_upper;
- leftMostNormal = upperNormal[k];
- leftMostXYZ = upperXYZ[k];
- }
- else /*upperVerts[i][0] > lowerVerts[j][0]*/
- {
- bgntfan();
- glNormal3fv(upperNormal[i]);
- glVertex3fv(upperXYZ[i]);
-
- glNormal3fv(leftMostNormal);
- glVertex3fv(leftMostXYZ);
-
-
- /*find the last k>=j such that
- *lowerverts[k][0] < upperverts[i][0]
- */
- k=j;
- while(k< n_lower)
- {
- if(lower_val[k] >= upper_val[i])
- break;
- glNormal3fv(lowerNormal[k]);
- glVertex3fv(lowerXYZ[k]);
-
- k++;
- }
- endtfan();
-
- /*update j and leftMostV for next loop
- */
- j=k;
- leftMostV[0] = lower_val[j-1];
- leftMostV[1] = v_lower;
-
- leftMostNormal = lowerNormal[j-1];
- leftMostXYZ = lowerXYZ[j-1];
- }
- }
- }
- //clean up
- free(upperXYZ);
- free(lowerXYZ);
- free(upperNormal);
- free(lowerNormal);
-}
-
-/*triangulate a strip bounded by two lines which are parallel to V-axis
- *leftVerts: the verteces on the left line
- *rightVertx: the verteces on the right line
- *n_left >=1
- *n_right >=1
- */
-void OpenGLSurfaceEvaluator::inEvalVStrip(int n_left, REAL u_left, REAL* left_val, int n_right, REAL u_right, REAL* right_val)
-{
- int i,j,k,l;
- REAL botMostV[2];
- typedef REAL REAL3[3];
-
- REAL3* leftXYZ = (REAL3*) malloc(sizeof(REAL3)*n_left);
- assert(leftXYZ);
- REAL3* leftNormal = (REAL3*) malloc(sizeof(REAL3) * n_left);
- assert(leftNormal);
- REAL3* rightXYZ = (REAL3*) malloc(sizeof(REAL3)*n_right);
- assert(rightXYZ);
- REAL3* rightNormal = (REAL3*) malloc(sizeof(REAL3) * n_right);
- assert(rightNormal);
-
- inEvalVLine(n_left, u_left, left_val, 1, leftXYZ, leftNormal);
- inEvalVLine(n_right, u_right, right_val, 1, rightXYZ, rightNormal);
-
-
-
- REAL* botMostXYZ;
- REAL* botMostNormal;
-
- /*
- *the algorithm works by scanning from bot to top.
- *botMostV: the bot most of the remaining verteces (on both left and right).
- * it could an element of leftVerts or rightVerts.
- *i: leftVerts[i] is the first vertex to the top of botMostV on left line
- *j: rightVerts[j] is the first vertex to the top of botMostV on rightline */
-
- /*initialize i,j,and botMostV
- */
- if(left_val[0] <= right_val[0])
- {
- i=1;
- j=0;
-
- botMostV[0] = u_left;
- botMostV[1] = left_val[0];
- botMostXYZ = leftXYZ[0];
- botMostNormal = leftNormal[0];
- }
- else
- {
- i=0;
- j=1;
-
- botMostV[0] = u_right;
- botMostV[1] = right_val[0];
-
- botMostXYZ = rightXYZ[0];
- botMostNormal = rightNormal[0];
- }
-
- /*the main loop.
- *the invariance is that:
- *at the beginning of each loop, the meaning of i,j,and botMostV are
- *maintained
- */
- while(1)
- {
- if(i >= n_left) /*case1: no more in left*/
- {
- if(j<n_right-1) /*at least two vertices in right*/
- {
- bgntfan();
- glNormal3fv(botMostNormal);
- glVertex3fv(botMostXYZ);
-
- while(j<n_right){
- glNormal3fv(rightNormal[j]);
- glVertex3fv(rightXYZ[j]);
- j++;
-
- }
- endtfan();
- }
- break; /*exit the main loop*/
- }
- else if(j>= n_right) /*case2: no more in right*/
- {
- if(i<n_left-1) /*at least two vertices in left*/
- {
- bgntfan();
- glNormal3fv(botMostNormal);
- glVertex3fv(botMostXYZ);
-
- for(k=n_left-1; k>=i; k--) /*reverse order for two-side lighting*/
- {
- glNormal3fv(leftNormal[k]);
- glVertex3fv(leftXYZ[k]);
- }
-
- endtfan();
- }
- break; /*exit the main loop*/
- }
- else /* case3: neither is empty, plus the botMostV, there is at least one triangle to output*/
- {
- if(left_val[i] <= right_val[j])
- {
- bgntfan();
-
- glNormal3fv(rightNormal[j]);
- glVertex3fv(rightXYZ[j]);
-
- /*find the last k>=i such that
- *leftverts[k][0] <= rightverts[j][0]
- */
- k=i;
-
- while(k<n_left)
- {
- if(left_val[k] > right_val[j])
- break;
- k++;
-
- }
- k--;
-
-
- for(l=k; l>=i; l--)/*the reverse is for two-side lighting*/
- {
- glNormal3fv(leftNormal[l]);
- glVertex3fv(leftXYZ[l]);
-
- }
- glNormal3fv(botMostNormal);
- glVertex3fv(botMostXYZ);
-
- endtfan();
-
- /*update i and botMostV for next loop
- */
- i = k+1;
-
- botMostV[0] = u_left;
- botMostV[1] = left_val[k];
- botMostNormal = leftNormal[k];
- botMostXYZ = leftXYZ[k];
- }
- else /*left_val[i] > right_val[j])*/
- {
- bgntfan();
- glNormal3fv(leftNormal[i]);
- glVertex3fv(leftXYZ[i]);
-
- glNormal3fv(botMostNormal);
- glVertex3fv(botMostXYZ);
-
-
- /*find the last k>=j such that
- *rightverts[k][0] < leftverts[i][0]
- */
- k=j;
- while(k< n_right)
- {
- if(right_val[k] >= left_val[i])
- break;
- glNormal3fv(rightNormal[k]);
- glVertex3fv(rightXYZ[k]);
-
- k++;
- }
- endtfan();
-
- /*update j and botMostV for next loop
- */
- j=k;
- botMostV[0] = u_right;
- botMostV[1] = right_val[j-1];
-
- botMostNormal = rightNormal[j-1];
- botMostXYZ = rightXYZ[j-1];
- }
- }
- }
- //clean up
- free(leftXYZ);
- free(rightXYZ);
- free(leftNormal);
- free(rightNormal);
-}
-
-/*-----------------------begin evalMachine-------------------*/
-void OpenGLSurfaceEvaluator::inMap2fEM(int which, int k,
- REAL ulower,
- REAL uupper,
- int ustride,
- int uorder,
- REAL vlower,
- REAL vupper,
- int vstride,
- int vorder,
- REAL *ctlPoints)
-{
- int i,j,x;
- surfEvalMachine *temp_em;
- switch(which){
- case 0: //vertex
- vertex_flag = 1;
- temp_em = &em_vertex;
- break;
- case 1: //normal
- normal_flag = 1;
- temp_em = &em_normal;
- break;
- case 2: //color
- color_flag = 1;
- temp_em = &em_color;
- break;
- default:
- texcoord_flag = 1;
- temp_em = &em_texcoord;
- break;
- }
-
- REAL *data = temp_em->ctlPoints;
-
- temp_em->uprime = -1;//initilized
- temp_em->vprime = -1;
-
- temp_em->k = k;
- temp_em->u1 = ulower;
- temp_em->u2 = uupper;
- temp_em->ustride = ustride;
- temp_em->uorder = uorder;
- temp_em->v1 = vlower;
- temp_em->v2 = vupper;
- temp_em->vstride = vstride;
- temp_em->vorder = vorder;
-
- /*copy the contrl points from ctlPoints to global_ev_ctlPoints*/
- for (i=0; i<uorder; i++) {
- for (j=0; j<vorder; j++) {
- for (x=0; x<k; x++) {
- data[x] = ctlPoints[x];
- }
- ctlPoints += vstride;
- data += k;
- }
- ctlPoints += ustride - vstride * vorder;
- }
-}
-
-void OpenGLSurfaceEvaluator::inDoDomain2WithDerivsEM(surfEvalMachine *em, REAL u, REAL v,
- REAL *retPoint, REAL *retdu, REAL *retdv)
-{
- int j, row, col;
- REAL the_uprime;
- REAL the_vprime;
- REAL p;
- REAL pdv;
- REAL *data;
-
- if((em->u2 == em->u1) || (em->v2 == em->v1))
- return;
- the_uprime = (u - em->u1) / (em->u2 - em->u1);
- the_vprime = (v - em->v1) / (em->v2 - em->v1);
-
- /* Compute coefficients for values and derivs */
-
- /* Use already cached values if possible */
- if(em->uprime != the_uprime) {
- inPreEvaluateWithDeriv(em->uorder, the_uprime, em->ucoeff, em->ucoeffDeriv);
- em->uprime = the_uprime;
- }
- if (em->vprime != the_vprime) {
- inPreEvaluateWithDeriv(em->vorder, the_vprime, em->vcoeff, em->vcoeffDeriv);
- em->vprime = the_vprime;
- }
-
- for (j = 0; j < em->k; j++) {
- data=em->ctlPoints+j;
- retPoint[j] = retdu[j] = retdv[j] = 0.0;
- for (row = 0; row < em->uorder; row++) {
- /*
- ** Minor optimization.
- ** The col == 0 part of the loop is extracted so we don't
- ** have to initialize p and pdv to 0.
- */
- p = em->vcoeff[0] * (*data);
- pdv = em->vcoeffDeriv[0] * (*data);
- data += em->k;
- for (col = 1; col < em->vorder; col++) {
- /* Incrementally build up p, pdv value */
- p += em->vcoeff[col] * (*data);
- pdv += em->vcoeffDeriv[col] * (*data);
- data += em->k;
- }
- /* Use p, pdv value to incrementally add up r, du, dv */
- retPoint[j] += em->ucoeff[row] * p;
- retdu[j] += em->ucoeffDeriv[row] * p;
- retdv[j] += em->ucoeff[row] * pdv;
- }
- }
-}
-
-void OpenGLSurfaceEvaluator::inDoDomain2EM(surfEvalMachine *em, REAL u, REAL v,
- REAL *retPoint)
-{
- int j, row, col;
- REAL the_uprime;
- REAL the_vprime;
- REAL p;
- REAL *data;
-
- if((em->u2 == em->u1) || (em->v2 == em->v1))
- return;
- the_uprime = (u - em->u1) / (em->u2 - em->u1);
- the_vprime = (v - em->v1) / (em->v2 - em->v1);
-
- /* Compute coefficients for values and derivs */
-
- /* Use already cached values if possible */
- if(em->uprime != the_uprime) {
- inPreEvaluate(em->uorder, the_uprime, em->ucoeff);
- em->uprime = the_uprime;
- }
- if (em->vprime != the_vprime) {
- inPreEvaluate(em->vorder, the_vprime, em->vcoeff);
- em->vprime = the_vprime;
- }
-
- for (j = 0; j < em->k; j++) {
- data=em->ctlPoints+j;
- retPoint[j] = 0.0;
- for (row = 0; row < em->uorder; row++) {
- /*
- ** Minor optimization.
- ** The col == 0 part of the loop is extracted so we don't
- ** have to initialize p and pdv to 0.
- */
- p = em->vcoeff[0] * (*data);
- data += em->k;
- for (col = 1; col < em->vorder; col++) {
- /* Incrementally build up p, pdv value */
- p += em->vcoeff[col] * (*data);
- data += em->k;
- }
- /* Use p, pdv value to incrementally add up r, du, dv */
- retPoint[j] += em->ucoeff[row] * p;
- }
- }
-}
-
-
-void OpenGLSurfaceEvaluator::inDoEvalCoord2EM(REAL u, REAL v)
-{
- REAL temp_vertex[5];
- REAL temp_normal[3];
- REAL temp_color[4];
- REAL temp_texcoord[4];
-
- if(texcoord_flag)
- {
- inDoDomain2EM(&em_texcoord, u,v, temp_texcoord);
- texcoordCallBack(temp_texcoord, userData);
- }
- if(color_flag)
- {
- inDoDomain2EM(&em_color, u,v, temp_color);
- colorCallBack(temp_color, userData);
- }
-
- if(normal_flag) //there is a normla map
- {
- inDoDomain2EM(&em_normal, u,v, temp_normal);
- normalCallBack(temp_normal, userData);
-
- if(vertex_flag)
- {
- inDoDomain2EM(&em_vertex, u,v,temp_vertex);
- if(em_vertex.k == 4)
- {
- temp_vertex[0] /= temp_vertex[3];
- temp_vertex[1] /= temp_vertex[3];
- temp_vertex[2] /= temp_vertex[3];
- }
- temp_vertex[3]=u;
- temp_vertex[4]=v;
- vertexCallBack(temp_vertex, userData);
- }
- }
- else if(auto_normal_flag) //no normal map but there is a normal callbackfunctin
- {
- REAL du[4];
- REAL dv[4];
-
- /*compute homegeneous point and partial derivatives*/
- inDoDomain2WithDerivsEM(&em_vertex, u,v,temp_vertex,du,dv);
-
- if(em_vertex.k ==4)
- inComputeFirstPartials(temp_vertex, du, dv);
-
-#ifdef AVOID_ZERO_NORMAL
- if(myabs(dv[0]) <= MYZERO && myabs(dv[1]) <= MYZERO && myabs(dv[2]) <= MYZERO)
- {
-
- REAL tempdu[4];
- REAL tempdata[4];
- REAL u1 = em_vertex.u1;
- REAL u2 = em_vertex.u2;
- if(u-MYDELTA*(u2-u1) < u1)
- u = u+ MYDELTA*(u2-u1);
- else
- u = u-MYDELTA*(u2-u1);
- inDoDomain2WithDerivsEM(&em_vertex,u,v, tempdata, tempdu, dv);
-
- if(em_vertex.k ==4)
- inComputeFirstPartials(temp_vertex, du, dv);
- }
- else if(myabs(du[0]) <= MYZERO && myabs(du[1]) <= MYZERO && myabs(du[2]) <= MYZERO)
- {
- REAL tempdv[4];
- REAL tempdata[4];
- REAL v1 = em_vertex.v1;
- REAL v2 = em_vertex.v2;
- if(v-MYDELTA*(v2-v1) < v1)
- v = v+ MYDELTA*(v2-v1);
- else
- v = v-MYDELTA*(v2-v1);
- inDoDomain2WithDerivsEM(&em_vertex,u,v, tempdata, du, tempdv);
-
- if(em_vertex.k ==4)
- inComputeFirstPartials(temp_vertex, du, dv);
- }
-#endif
-
- /*compute normal*/
- switch(em_vertex.k){
- case 3:
-
- inComputeNormal2(du, dv, temp_normal);
- break;
- case 4:
-
-// inComputeFirstPartials(temp_vertex, du, dv);
- inComputeNormal2(du, dv, temp_normal);
-
- /*transform the homegeneous coordinate of retPoint into inhomogenous one*/
- temp_vertex[0] /= temp_vertex[3];
- temp_vertex[1] /= temp_vertex[3];
- temp_vertex[2] /= temp_vertex[3];
- break;
- }
- normalCallBack(temp_normal, userData);
- temp_vertex[3] = u;
- temp_vertex[4] = v;
- vertexCallBack(temp_vertex, userData);
-
- }/*end if auto_normal*/
- else //no normal map, and no normal callback function
- {
- if(vertex_flag)
- {
- inDoDomain2EM(&em_vertex, u,v,temp_vertex);
- if(em_vertex.k == 4)
- {
- temp_vertex[0] /= temp_vertex[3];
- temp_vertex[1] /= temp_vertex[3];
- temp_vertex[2] /= temp_vertex[3];
- }
- temp_vertex[3] = u;
- temp_vertex[4] = v;
- vertexCallBack(temp_vertex, userData);
- }
- }
-}
-
-
-void OpenGLSurfaceEvaluator::inBPMEvalEM(bezierPatchMesh* bpm)
-{
- int i,j,k;
- float u,v;
-
- int ustride;
- int vstride;
-
-#ifdef USE_LOD
- if(bpm->bpatch != NULL)
- {
- bezierPatch* p=bpm->bpatch;
- ustride = p->dimension * p->vorder;
- vstride = p->dimension;
-
- glMap2f( (p->dimension == 3)? GL_MAP2_VERTEX_3 : GL_MAP2_VERTEX_4,
- p->umin,
- p->umax,
- ustride,
- p->uorder,
- p->vmin,
- p->vmax,
- vstride,
- p->vorder,
- p->ctlpoints);
-
-
-/*
- inMap2fEM(0, p->dimension,
- p->umin,
- p->umax,
- ustride,
- p->uorder,
- p->vmin,
- p->vmax,
- vstride,
- p->vorder,
- p->ctlpoints);
-*/
- }
-#else
-
- if(bpm->bpatch != NULL){
- bezierPatch* p = bpm->bpatch;
- ustride = p->dimension * p->vorder;
- vstride = p->dimension;
- inMap2fEM(0, p->dimension,
- p->umin,
- p->umax,
- ustride,
- p->uorder,
- p->vmin,
- p->vmax,
- vstride,
- p->vorder,
- p->ctlpoints);
- }
- if(bpm->bpatch_normal != NULL){
- bezierPatch* p = bpm->bpatch_normal;
- ustride = p->dimension * p->vorder;
- vstride = p->dimension;
- inMap2fEM(1, p->dimension,
- p->umin,
- p->umax,
- ustride,
- p->uorder,
- p->vmin,
- p->vmax,
- vstride,
- p->vorder,
- p->ctlpoints);
- }
- if(bpm->bpatch_color != NULL){
- bezierPatch* p = bpm->bpatch_color;
- ustride = p->dimension * p->vorder;
- vstride = p->dimension;
- inMap2fEM(2, p->dimension,
- p->umin,
- p->umax,
- ustride,
- p->uorder,
- p->vmin,
- p->vmax,
- vstride,
- p->vorder,
- p->ctlpoints);
- }
- if(bpm->bpatch_texcoord != NULL){
- bezierPatch* p = bpm->bpatch_texcoord;
- ustride = p->dimension * p->vorder;
- vstride = p->dimension;
- inMap2fEM(3, p->dimension,
- p->umin,
- p->umax,
- ustride,
- p->uorder,
- p->vmin,
- p->vmax,
- vstride,
- p->vorder,
- p->ctlpoints);
- }
-#endif
-
-
- k=0;
- for(i=0; i<bpm->index_length_array; i++)
- {
-#ifdef USE_LOD
- if(bpm->type_array[i] == GL_POLYGON) //a mesh
- {
- GLfloat *temp = bpm->UVarray+k;
- GLfloat u0 = temp[0];
- GLfloat v0 = temp[1];
- GLfloat u1 = temp[2];
- GLfloat v1 = temp[3];
- GLint nu = (GLint) ( temp[4]);
- GLint nv = (GLint) ( temp[5]);
- GLint umin = (GLint) ( temp[6]);
- GLint vmin = (GLint) ( temp[7]);
- GLint umax = (GLint) ( temp[8]);
- GLint vmax = (GLint) ( temp[9]);
-
- glMapGrid2f(LOD_eval_level*nu, u0, u1, LOD_eval_level*nv, v0, v1);
- glEvalMesh2(GL_FILL, LOD_eval_level*umin, LOD_eval_level*umax, LOD_eval_level*vmin, LOD_eval_level*vmax);
- }
- else
- {
- LOD_eval(bpm->length_array[i], bpm->UVarray+k, bpm->type_array[i],
- 0
- );
- }
- k+= 2*bpm->length_array[i];
-
-#else //undef USE_LOD
-
-#ifdef CRACK_TEST
-if( bpm->bpatch->umin == 2 && bpm->bpatch->umax == 3
- && bpm->bpatch->vmin ==2 && bpm->bpatch->vmax == 3)
-{
-REAL vertex[4];
-REAL normal[4];
-#ifdef DEBUG
-printf("***number ****1\n");
-#endif
-
-beginCallBack(GL_QUAD_STRIP, NULL);
-inDoEvalCoord2EM(3.0, 3.0);
-inDoEvalCoord2EM(2.0, 3.0);
-inDoEvalCoord2EM(3.0, 2.7);
-inDoEvalCoord2EM(2.0, 2.7);
-inDoEvalCoord2EM(3.0, 2.0);
-inDoEvalCoord2EM(2.0, 2.0);
-endCallBack(NULL);
-
-beginCallBack(GL_TRIANGLE_STRIP, NULL);
-inDoEvalCoord2EM(2.0, 3.0);
-inDoEvalCoord2EM(2.0, 2.0);
-inDoEvalCoord2EM(2.0, 2.7);
-endCallBack(NULL);
-
-}
-if( bpm->bpatch->umin == 1 && bpm->bpatch->umax == 2
- && bpm->bpatch->vmin ==2 && bpm->bpatch->vmax == 3)
-{
-#ifdef DEBUG
-printf("***number 3\n");
-#endif
-beginCallBack(GL_QUAD_STRIP, NULL);
-inDoEvalCoord2EM(2.0, 3.0);
-inDoEvalCoord2EM(1.0, 3.0);
-inDoEvalCoord2EM(2.0, 2.3);
-inDoEvalCoord2EM(1.0, 2.3);
-inDoEvalCoord2EM(2.0, 2.0);
-inDoEvalCoord2EM(1.0, 2.0);
-endCallBack(NULL);
-
-beginCallBack(GL_TRIANGLE_STRIP, NULL);
-inDoEvalCoord2EM(2.0, 2.3);
-inDoEvalCoord2EM(2.0, 2.0);
-inDoEvalCoord2EM(2.0, 3.0);
-endCallBack(NULL);
-
-}
-return;
-#endif //CRACK_TEST
-
- beginCallBack(bpm->type_array[i], userData);
-
- for(j=0; j<bpm->length_array[i]; j++)
- {
- u = bpm->UVarray[k];
- v = bpm->UVarray[k+1];
-#ifdef USE_LOD
- LOD_EVAL_COORD(u,v);
-// glEvalCoord2f(u,v);
-#else
-
-#ifdef GENERIC_TEST
- float temp_normal[3];
- float temp_vertex[3];
- if(temp_signal == 0)
- {
- gTessVertexSphere(u,v, temp_normal, temp_vertex);
-//printf("normal=(%f,%f,%f)\n", temp_normal[0], temp_normal[1], temp_normal[2])//printf("veretx=(%f,%f,%f)\n", temp_vertex[0], temp_vertex[1], temp_vertex[2]);
- normalCallBack(temp_normal, userData);
- vertexCallBack(temp_vertex, userData);
- }
- else if(temp_signal == 1)
- {
- gTessVertexCyl(u,v, temp_normal, temp_vertex);
-//printf("normal=(%f,%f,%f)\n", temp_normal[0], temp_normal[1], temp_normal[2])//printf("veretx=(%f,%f,%f)\n", temp_vertex[0], temp_vertex[1], temp_vertex[2]);
- normalCallBack(temp_normal, userData);
- vertexCallBack(temp_vertex, userData);
- }
- else
-#endif //GENERIC_TEST
-
- inDoEvalCoord2EM(u,v);
-
-#endif //USE_LOD
-
- k += 2;
- }
- endCallBack(userData);
-
-#endif //USE_LOD
- }
-}
-
-void OpenGLSurfaceEvaluator::inBPMListEvalEM(bezierPatchMesh* list)
-{
- bezierPatchMesh* temp;
- for(temp = list; temp != NULL; temp = temp->next)
- {
- inBPMEvalEM(temp);
- }
-}
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * mystdio.h
- *
- */
-
-#ifndef __glumystdio_h_
-#define __glumystdio_h_
-
-#ifdef STANDALONE
-inline void _glu_dprintf( const char *, ... ) { }
-#endif
-
-#ifdef LIBRARYBUILD
-#ifndef NDEBUG
-#include <stdio.h>
-#define _glu_dprintf printf
-#else
-inline void _glu_dprintf( const char *, ... ) { }
-#endif
-#endif
-
-#ifdef GLBUILD
-inline void _glu_dprintf( const char *, ... ) { }
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif /* __glumystdio_h_ */
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * mystdlib.h
- *
- */
-
-#ifndef __glumystdlib_h_
-#define __glumystdlib_h_
-
-#ifdef STANDALONE
-typedef unsigned int size_t;
-extern "C" void abort( void );
-extern "C" void * malloc( size_t );
-extern "C" void free( void * );
-#endif
-
-#ifdef LIBRARYBUILD
-#include <stdlib.h>
-#endif
-
-#ifdef GLBUILD
-typedef unsigned int size_t;
-extern "C" void abort( void );
-extern "C" void * malloc( size_t );
-extern "C" void free( void * );
-#endif
-
-#endif /* __glumystdlib_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * arc.c++
- *
- */
-
-#include <stdio.h>
-#include "glimports.h"
-#include "mystdio.h"
-#include "myassert.h"
-#include "arc.h"
-#include "bin.h"
-#include "pwlarc.h"
-#include "simplemath.h"
-
-/* local preprocessor definitions */
-#define ZERO 0.00001/*0.000001*/
-
-const int Arc::bezier_tag = (1<<13);
-const int Arc::arc_tag = (1<<3);
-const int Arc::tail_tag = (1<<6);
-
-/*--------------------------------------------------------------------------
- * makeSide - attach a pwl arc to an arc and mark it as a border arc
- *--------------------------------------------------------------------------
- */
-
-void
-Arc::makeSide( PwlArc *pwl, arc_side side )
-{
- assert( pwl != 0);
- assert( pwlArc == 0 );
- assert( pwl->npts > 0 );
- assert( pwl->pts != 0);
- pwlArc = pwl;
- clearbezier();
- setside( side );
-}
-
-
-/*--------------------------------------------------------------------------
- * numpts - count number of points on arc loop
- *--------------------------------------------------------------------------
- */
-
-int
-Arc::numpts( void )
-{
- Arc_ptr jarc = this;
- int npts = 0;
- do {
- npts += jarc->pwlArc->npts;
- jarc = jarc->next;
- } while( jarc != this );
- return npts;
-}
-
-/*--------------------------------------------------------------------------
- * markverts - mark each point with id of arc
- *--------------------------------------------------------------------------
- */
-
-void
-Arc::markverts( void )
-{
- Arc_ptr jarc = this;
-
- do {
- TrimVertex *p = jarc->pwlArc->pts;
- for( int i=0; i<jarc->pwlArc->npts; i++ )
- p[i].nuid = jarc->nuid;
- jarc = jarc->next;
- } while( jarc != this );
-}
-
-/*--------------------------------------------------------------------------
- * getextrema - find axis extrema on arc loop
- *--------------------------------------------------------------------------
- */
-
-void
-Arc::getextrema( Arc_ptr extrema[4] )
-{
- REAL leftpt, botpt, rightpt, toppt;
-
- extrema[0] = extrema[1] = extrema[2] = extrema[3] = this;
-
- leftpt = rightpt = this->tail()[0];
- botpt = toppt = this->tail()[1];
-
- for( Arc_ptr jarc = this->next; jarc != this; jarc = jarc->next ) {
- if ( jarc->tail()[0] < leftpt ||
- (jarc->tail()[0] <= leftpt && jarc->rhead()[0]<=leftpt)) {
- leftpt = jarc->pwlArc->pts->param[0];
- extrema[1] = jarc;
- }
- if ( jarc->tail()[0] > rightpt ||
- (jarc->tail()[0] >= rightpt && jarc->rhead()[0] >= rightpt)) {
- rightpt = jarc->pwlArc->pts->param[0];
- extrema[3] = jarc;
- }
- if ( jarc->tail()[1] < botpt ||
- (jarc->tail()[1] <= botpt && jarc->rhead()[1] <= botpt )) {
- botpt = jarc->pwlArc->pts->param[1];
- extrema[2] = jarc;
- }
- if ( jarc->tail()[1] > toppt ||
- (jarc->tail()[1] >= toppt && jarc->rhead()[1] >= toppt)) {
- toppt = jarc->pwlArc->pts->param[1];
- extrema[0] = jarc;
- }
- }
-}
-
-
-/*-------------------------------------------------------------------------
- * show - print to the stdout the vertices of a pwl arc
- *-------------------------------------------------------------------------
- */
-
-void
-Arc::show()
-{
-#ifndef NDEBUG
- _glu_dprintf( "\tPWLARC NP: %d FL: 1\n", pwlArc->npts );
- for( int i = 0; i < pwlArc->npts; i++ ) {
- _glu_dprintf( "\t\tVERTEX %f %f\n", pwlArc->pts[i].param[0],
- pwlArc->pts[i].param[1] );
- }
-#endif
-}
-
-/*-------------------------------------------------------------------------
- * print - print out the vertices of all pwl arcs on a loop
- *-------------------------------------------------------------------------
- */
-
-void
-Arc::print( void )
-{
- Arc_ptr jarc = this;
-
-#ifndef NDEBUG
- _glu_dprintf( "BGNTRIM\n" );
-#endif
- do {
- jarc->show( );
- jarc = jarc->next;
- } while (jarc != this);
-#ifndef NDEBUG
- _glu_dprintf("ENDTRIM\n" );
-#endif
-}
-
-/*-------------------------------------------------------------------------
- * isDisconnected - check if tail of arc and head of prev meet
- *-------------------------------------------------------------------------
- */
-
-int
-Arc::isDisconnected( void )
-{
- if( pwlArc == 0 ) return 0;
- if( prev->pwlArc == 0 ) return 0;
-
- REAL *p0 = tail();
- REAL *p1 = prev->rhead();
-
- if( ((p0[0] - p1[0]) > ZERO) || ((p1[0] - p0[0]) > ZERO) ||
- ((p0[1] - p1[1]) > ZERO) || ((p1[1] - p0[1]) > ZERO) ) {
-#ifndef NDEBUG
- _glu_dprintf( "x coord = %f %f %f\n", p0[0], p1[0], p0[0] - p1[0] );
- _glu_dprintf( "y coord = %f %f %f\n", p0[1], p1[1], p0[1] - p1[1] );
-#endif
- return 1;
- } else {
- /* average two points together */
- p0[0] = p1[0] = (p1[0] + p0[0]) * 0.5;
- p0[1] = p1[1] = (p1[1] + p0[1]) * 0.5;
- return 0;
- }
-}
-
-/*-------------------------------------------------------------------------
- * neq_vert - assert that two 2D vertices are not equal
- *-------------------------------------------------------------------------
- */
-
-inline static int
-neq_vert( REAL *v1, REAL *v2 )
-{
- return ((v1[0] != v2[0]) || (v1[1] != v2[1] )) ? 1 : 0;
-}
-
-/*-------------------------------------------------------------------------
- * check - verify consistency of a loop, including
- * 1) if pwl, no two consecutive vertices are identical
- * 2) the circular link pointers are valid
- * 3) the geometric info at the head and tail are consistent
- *-------------------------------------------------------------------------
- */
-
-int
-Arc::check( void )
-{
- if( this == 0 ) return 1;
- Arc_ptr jarc = this;
- do {
- assert( (jarc->pwlArc != 0) || (jarc->bezierArc != 0) );
-
- if (jarc->prev == 0 || jarc->next == 0) {
-#ifndef NDEBUG
- _glu_dprintf( "checkjarc:null next/prev pointer\n");
- jarc->print( );
-#endif
- return 0;
- }
-
- if (jarc->next->prev != jarc) {
-#ifndef NDEBUG
- _glu_dprintf( "checkjarc: pointer linkage screwed up\n");
- jarc->print( );
-#endif
- return 0;
- }
-
- if( jarc->pwlArc ) {
-#ifndef NDEBUG
- assert( jarc->pwlArc->npts >= 1 );
- assert( jarc->pwlArc->npts < 100000 );
-/*
- for( int i=0; i < jarc->pwlArc->npts-1; i++ )
- assert( neq_vert( jarc->pwlArc->pts[i].param,
- jarc->pwlArc->pts[i+1].param) );
-*/
-#endif
- if( jarc->prev->pwlArc ) {
- if( jarc->tail()[1] != jarc->prev->rhead()[1] ) {
-#ifndef NDEBUG
- _glu_dprintf( "checkjarc: geometric linkage screwed up 1\n");
- jarc->prev->show();
- jarc->show();
-#endif
- return 0;
- }
- if( jarc->tail()[0] != jarc->prev->rhead()[0] ) {
-
-#ifndef NDEBUG
- _glu_dprintf( "checkjarc: geometric linkage screwed up 2\n");
- jarc->prev->show();
- jarc->show();
-#endif
- return 0;
- }
- }
- if( jarc->next->pwlArc ) {
- if( jarc->next->tail()[0] != jarc->rhead()[0] ) {
-#ifndef NDEBUG
- _glu_dprintf( "checkjarc: geometric linkage screwed up 3\n");
- jarc->show();
- jarc->next->show();
-#endif
- return 0;
- }
- if( jarc->next->tail()[1] != jarc->rhead()[1] ) {
-#ifndef NDEBUG
- _glu_dprintf( "checkjarc: geometric linkage screwed up 4\n");
- jarc->show();
- jarc->next->show();
-#endif
- return 0;
- }
- }
- if( jarc->isbezier() ) {
- assert( jarc->pwlArc->npts == 2 );
- assert( (jarc->pwlArc->pts[0].param[0] == \
- jarc->pwlArc->pts[1].param[0]) ||\
- (jarc->pwlArc->pts[0].param[1] == \
- jarc->pwlArc->pts[1].param[1]) );
- }
- }
- jarc = jarc->next;
- } while (jarc != this);
- return 1;
-}
-
-
-#define TOL 0.00001
-
-inline long tooclose( REAL x, REAL y )
-{
- return (glu_abs(x-y) < TOL) ? 1 : 0;
-}
-
-
-/*--------------------------------------------------------------------------
- * append - append a jordan arc to a circularly linked list
- *--------------------------------------------------------------------------
- */
-
-Arc_ptr
-Arc::append( Arc_ptr jarc )
-{
- if( jarc != 0 ) {
- next = jarc->next;
- prev = jarc;
- next->prev = prev->next = this;
- } else {
- next = prev = this;
- }
- return this;
-}
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * arc.h
- *
- */
-
-#ifndef __gluarc_h_
-#define __gluarc_h_
-
-#include "myassert.h"
-#include "bufpool.h"
-#include "mystdio.h"
-#include "types.h"
-#include "pwlarc.h"
-#include "trimvertex.h"
-
-class Bin;
-class Arc;
-struct BezierArc;
-
-typedef class Arc *Arc_ptr;
-
-enum arc_side { arc_none = 0, arc_right, arc_top, arc_left, arc_bottom };
-
-
-class Arc: public PooledObj { /* an arc, in two list, the trim list and bin */
-
-public:
- static const int bezier_tag;
- static const int arc_tag;
- static const int tail_tag;
- Arc_ptr prev; /* trim list pointer */
- Arc_ptr next; /* trim list pointer */
- Arc_ptr link; /* bin pointers */
- BezierArc * bezierArc; /* associated bezier arc */
- PwlArc * pwlArc; /* associated pwl arc */
- long type; /* curve type */
- long nuid;
-
- inline Arc( Arc *, PwlArc * );
- inline Arc( arc_side, long );
-
- Arc_ptr append( Arc_ptr );
- int check( void );
- int isMonotone( void );
- int isDisconnected( void );
- int numpts( void );
- void markverts( void );
- void getextrema( Arc_ptr[4] );
- void print( void );
- void show( void );
- void makeSide( PwlArc *, arc_side );
- inline int isTessellated() { return pwlArc ? 1 : 0; }
- inline long isbezier() { return type & bezier_tag; }
- inline void setbezier() { type |= bezier_tag; }
- inline void clearbezier() { type &= ~bezier_tag; }
- inline long npts() { return pwlArc->npts; }
- inline TrimVertex * pts() { return pwlArc->pts; }
- inline REAL * tail() { return pwlArc->pts[0].param; }
- inline REAL * head() { return next->pwlArc->pts[0].param; }
- inline REAL * rhead() { return pwlArc->pts[pwlArc->npts-1].param; }
- inline long ismarked() { return type & arc_tag; }
- inline void setmark() { type |= arc_tag; }
- inline void clearmark() { type &= (~arc_tag); }
- inline void clearside() { type &= ~(0x7 << 8); }
- inline void setside( arc_side s ) { clearside(); type |= (((long)s)<<8); }
- inline arc_side getside() { return (arc_side) ((type>>8) & 0x7); }
- inline int getitail() { return type & tail_tag; }
- inline void setitail() { type |= tail_tag; }
- inline void clearitail() { type &= (~tail_tag); }
-};
-
-/*--------------------------------------------------------------------------
- * Arc - initialize a new Arc with the same type and uid of
- * a given Arc and a given pwl arc
- *--------------------------------------------------------------------------
- */
-
-inline
-Arc::Arc( Arc *j, PwlArc *p )
-{
- prev = NULL;
- next = NULL;
- link = NULL;
- bezierArc = NULL;
- pwlArc = p;
- type = j->type;
- nuid = j->nuid;
-}
-
-/*--------------------------------------------------------------------------
- * Arc - initialize a new Arc with the same type and uid of
- * a given Arc and a given pwl arc
- *--------------------------------------------------------------------------
- */
-
-inline
-Arc::Arc( arc_side side, long _nuid )
-{
- prev = NULL;
- next = NULL;
- link = NULL;
- bezierArc = NULL;
- pwlArc = NULL;
- type = 0;
- setside( side );
- nuid = _nuid;
-}
-
-#endif /* __gluarc_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * arcsorter.c++
- *
- */
-
-#ifndef __gluarcsorter_c_
-#define __gluarcsorter_c_
-
-#include "glimports.h"
-#include "arc.h"
-#include "arcsorter.h"
-#include "subdivider.h"
-
-ArcSorter::ArcSorter(Subdivider &s) : Sorter( sizeof( Arc ** ) ), subdivider(s)
-{
-}
-
-int
-ArcSorter::qscmp( char *, char * )
-{
- _glu_dprintf( "ArcSorter::qscmp: pure virtual called\n" );
- return 0;
-}
-
-void
-ArcSorter::qsort( Arc **a, int n )
-{
- Sorter::qsort( (void *) a, n );
-}
-
-void
-ArcSorter::qsexc( char *i, char *j )// i<-j, j<-i
-{
- Arc **jarc1 = (Arc **) i;
- Arc **jarc2 = (Arc **) j;
- Arc *tmp = *jarc1;
- *jarc1 = *jarc2;
- *jarc2 = tmp;
-}
-
-void
-ArcSorter::qstexc( char *i, char *j, char *k )// i<-k, k<-j, j<-i
-{
- Arc **jarc1 = (Arc **) i;
- Arc **jarc2 = (Arc **) j;
- Arc **jarc3 = (Arc **) k;
- Arc *tmp = *jarc1;
- *jarc1 = *jarc3;
- *jarc3 = *jarc2;
- *jarc2 = tmp;
-}
-
-
-ArcSdirSorter::ArcSdirSorter( Subdivider &s ) : ArcSorter(s)
-{
-}
-
-int
-ArcSdirSorter::qscmp( char *i, char *j )
-{
- Arc *jarc1 = *(Arc **) i;
- Arc *jarc2 = *(Arc **) j;
-
- int v1 = (jarc1->getitail() ? 0 : (jarc1->pwlArc->npts - 1));
- int v2 = (jarc2->getitail() ? 0 : (jarc2->pwlArc->npts - 1));
-
- REAL diff = jarc1->pwlArc->pts[v1].param[1] -
- jarc2->pwlArc->pts[v2].param[1];
-
- if( diff < 0.0)
- return -1;
- else if( diff > 0.0)
- return 1;
- else {
- if( v1 == 0 ) {
- if( jarc2->tail()[0] < jarc1->tail()[0] ) {
- return subdivider.ccwTurn_sl( jarc2, jarc1 ) ? 1 : -1;
- } else {
- return subdivider.ccwTurn_sr( jarc2, jarc1 ) ? -1 : 1;
- }
- } else {
- if( jarc2->head()[0] < jarc1->head()[0] ) {
- return subdivider.ccwTurn_sl( jarc1, jarc2 ) ? -1 : 1;
- } else {
- return subdivider.ccwTurn_sr( jarc1, jarc2 ) ? 1 : -1;
- }
- }
- }
-}
-
-ArcTdirSorter::ArcTdirSorter( Subdivider &s ) : ArcSorter(s)
-{
-}
-
-/*----------------------------------------------------------------------------
- * ArcTdirSorter::qscmp -
- * compare two axis monotone arcs that are incident
- * to the line T == compare_value. Determine which of the
- * two intersects that line with a LESSER S value. If
- * jarc1 does, return 1. If jarc2 does, return -1.
- *----------------------------------------------------------------------------
- */
-int
-ArcTdirSorter::qscmp( char *i, char *j )
-{
- Arc *jarc1 = *(Arc **) i;
- Arc *jarc2 = *(Arc **) j;
-
- int v1 = (jarc1->getitail() ? 0 : (jarc1->pwlArc->npts - 1));
- int v2 = (jarc2->getitail() ? 0 : (jarc2->pwlArc->npts - 1));
-
- REAL diff = jarc1->pwlArc->pts[v1].param[0] -
- jarc2->pwlArc->pts[v2].param[0];
-
- if( diff < 0.0)
- return 1;
- else if( diff > 0.0)
- return -1;
- else {
- if( v1 == 0 ) {
- if (jarc2->tail()[1] < jarc1->tail()[1]) {
- return subdivider.ccwTurn_tl( jarc2, jarc1 ) ? 1 : -1;
- } else {
- return subdivider.ccwTurn_tr( jarc2, jarc1 ) ? -1 : 1;
- }
- } else {
- if( jarc2->head()[1] < jarc1->head()[1] ) {
- return subdivider.ccwTurn_tl( jarc1, jarc2 ) ? -1 : 1;
- } else {
- return subdivider.ccwTurn_tr( jarc1, jarc2 ) ? 1 : -1;
- }
- }
- }
-}
-
-
-
-#endif /* __gluarcsorter_c_ */
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * arcsorter.h
- *
- */
-
-#ifndef __gluarcsorter_h_
-#define __gluarcsorter_h_
-
-#include "sorter.h"
-
-class Arc;
-class Subdivider;
-
-class ArcSorter : private Sorter {
-public:
- ArcSorter(Subdivider &);
- void qsort( Arc **a, int n );
-protected:
- virtual int qscmp( char *, char * );
- Subdivider& subdivider;
-private:
- void qsexc( char *i, char *j ); // i<-j, j<-i
- void qstexc( char *i, char *j, char *k ); // i<-k, k<-j, j<-i
-};
-
-
-class ArcSdirSorter : public ArcSorter {
-public:
- ArcSdirSorter( Subdivider & );
-private:
- int qscmp( char *, char * );
-};
-
-
-class ArcTdirSorter : public ArcSorter {
-public:
- ArcTdirSorter( Subdivider & );
-private:
- int qscmp( char *, char * );
-};
-
-#endif /* __gluarcsorter_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * arctessellator.c++
- *
- */
-
-#include "glimports.h"
-#include "mystdio.h"
-#include "myassert.h"
-#include "arctess.h"
-#include "bufpool.h"
-#include "simplemath.h"
-#include "bezierarc.h"
-#include "trimvertex.h"
-#include "trimvertpool.h"
-
-#define NOELIMINATION
-
-#define steps_function(large, small, rate) (max(1, 1+ (int) ((large-small)/rate)));
-
-/*-----------------------------------------------------------------------------
- * ArcTessellator - construct an ArcTessellator
- *-----------------------------------------------------------------------------
- */
-
-ArcTessellator::ArcTessellator( TrimVertexPool& t, Pool& p )
- : pwlarcpool(p), trimvertexpool(t)
-{
-}
-
-/*-----------------------------------------------------------------------------
- * ~ArcTessellator - destroy an ArcTessellator
- *-----------------------------------------------------------------------------
- */
-
-ArcTessellator::~ArcTessellator( void )
-{
-}
-
-/*-----------------------------------------------------------------------------
- * bezier - construct a bezier arc and attach it to an Arc
- *-----------------------------------------------------------------------------
- */
-
-void
-ArcTessellator::bezier( Arc *arc, REAL s1, REAL s2, REAL t1, REAL t2 )
-{
- assert( arc != 0 );
- assert( ! arc->isTessellated() );
-
-#ifndef NDEBUG
- switch( arc->getside() ) {
- case arc_left:
- assert( s1 == s2 );
- assert( t2 < t1 );
- break;
- case arc_right:
- assert( s1 == s2 );
- assert( t1 < t2 );
- break;
- case arc_top:
- assert( t1 == t2 );
- assert( s2 < s1 );
- break;
- case arc_bottom:
- assert( t1 == t2 );
- assert( s1 < s2 );
- break;
- case arc_none:
- (void) abort();
- break;
- }
-#endif
-
- TrimVertex *p = trimvertexpool.get(2);
- arc->pwlArc = new(pwlarcpool) PwlArc( 2, p );
- p[0].param[0] = s1;
- p[0].param[1] = t1;
- p[1].param[0] = s2;
- p[1].param[1] = t2;
- assert( (s1 == s2) || (t1 == t2) );
- arc->setbezier();
-}
-
-
-/*-----------------------------------------------------------------------------
- * pwl_left - construct a left boundary pwl arc and attach it to an arc
- *-----------------------------------------------------------------------------
- */
-
-void
-ArcTessellator::pwl_left( Arc *arc, REAL s, REAL t1, REAL t2, REAL rate )
-{
- assert( t2 < t1 );
-
-/* if(rate <= 0.06) rate = 0.06;*/
-/* int nsteps = 1 + (int) ((t1 - t2) / rate ); */
- int nsteps = steps_function(t1, t2, rate);
-
-
- REAL stepsize = (t1 - t2) / (REAL) nsteps;
-
- TrimVertex *newvert = trimvertexpool.get( nsteps+1 );
- int i;
- for( i = nsteps; i > 0; i-- ) {
- newvert[i].param[0] = s;
- newvert[i].param[1] = t2;
- t2 += stepsize;
- }
- newvert[i].param[0] = s;
- newvert[i].param[1] = t1;
-
- arc->makeSide( new(pwlarcpool) PwlArc( nsteps+1, newvert ), arc_left );
-}
-
-/*-----------------------------------------------------------------------------
- * pwl_right - construct a right boundary pwl arc and attach it to an arc
- *-----------------------------------------------------------------------------
- */
-
-void
-ArcTessellator::pwl_right( Arc *arc, REAL s, REAL t1, REAL t2, REAL rate )
-{
- assert( t1 < t2 );
-
-/* if(rate <= 0.06) rate = 0.06;*/
-
-/* int nsteps = 1 + (int) ((t2 - t1) / rate ); */
- int nsteps = steps_function(t2,t1,rate);
- REAL stepsize = (t2 - t1) / (REAL) nsteps;
-
- TrimVertex *newvert = trimvertexpool.get( nsteps+1 );
- int i;
- for( i = 0; i < nsteps; i++ ) {
- newvert[i].param[0] = s;
- newvert[i].param[1] = t1;
- t1 += stepsize;
- }
- newvert[i].param[0] = s;
- newvert[i].param[1] = t2;
-
- arc->makeSide( new(pwlarcpool) PwlArc( nsteps+1, newvert ), arc_right );
-}
-
-
-/*-----------------------------------------------------------------------------
- * pwl_top - construct a top boundary pwl arc and attach it to an arc
- *-----------------------------------------------------------------------------
- */
-
-void
-ArcTessellator::pwl_top( Arc *arc, REAL t, REAL s1, REAL s2, REAL rate )
-{
- assert( s2 < s1 );
-
-/* if(rate <= 0.06) rate = 0.06;*/
-
-/* int nsteps = 1 + (int) ((s1 - s2) / rate ); */
- int nsteps = steps_function(s1,s2,rate);
- REAL stepsize = (s1 - s2) / (REAL) nsteps;
-
- TrimVertex *newvert = trimvertexpool.get( nsteps+1 );
- int i;
- for( i = nsteps; i > 0; i-- ) {
- newvert[i].param[0] = s2;
- newvert[i].param[1] = t;
- s2 += stepsize;
- }
- newvert[i].param[0] = s1;
- newvert[i].param[1] = t;
-
- arc->makeSide( new(pwlarcpool) PwlArc( nsteps+1, newvert ), arc_top );
-}
-
-/*-----------------------------------------------------------------------------
- * pwl_bottom - construct a bottom boundary pwl arc and attach it to an arc
- *-----------------------------------------------------------------------------
- */
-
-void
-ArcTessellator::pwl_bottom( Arc *arc, REAL t, REAL s1, REAL s2, REAL rate )
-{
- assert( s1 < s2 );
-
-/* if(rate <= 0.06) rate = 0.06;*/
-
-/* int nsteps = 1 + (int) ((s2 - s1) / rate ); */
- int nsteps = steps_function(s2,s1,rate);
- REAL stepsize = (s2 - s1) / (REAL) nsteps;
-
- TrimVertex *newvert = trimvertexpool.get( nsteps+1 );
- int i;
- for( i = 0; i < nsteps; i++ ) {
- newvert[i].param[0] = s1;
- newvert[i].param[1] = t;
- s1 += stepsize;
- }
- newvert[i].param[0] = s2;
- newvert[i].param[1] = t;
-
- arc->makeSide( new(pwlarcpool) PwlArc( nsteps+1, newvert ), arc_bottom );
-}
-
-/*-----------------------------------------------------------------------------
- * pwl - construct a pwl arc and attach it to an arc
- *-----------------------------------------------------------------------------
- */
-
-void
-ArcTessellator::pwl( Arc *arc, REAL s1, REAL s2, REAL t1, REAL t2, REAL rate )
-{
-
-/* if(rate <= 0.06) rate = 0.06;*/
-
- int snsteps = 1 + (int) (glu_abs(s2 - s1) / rate );
- int tnsteps = 1 + (int) (glu_abs(t2 - t1) / rate );
- int nsteps = max(1,max( snsteps, tnsteps ));
-
- REAL sstepsize = (s2 - s1) / (REAL) nsteps;
- REAL tstepsize = (t2 - t1) / (REAL) nsteps;
- TrimVertex *newvert = trimvertexpool.get( nsteps+1 );
- long i;
- for( i = 0; i < nsteps; i++ ) {
- newvert[i].param[0] = s1;
- newvert[i].param[1] = t1;
- s1 += sstepsize;
- t1 += tstepsize;
- }
- newvert[i].param[0] = s2;
- newvert[i].param[1] = t2;
-
- /* arc->makeSide( new(pwlarcpool) PwlArc( nsteps+1, newvert ), arc_bottom ); */
- arc->pwlArc = new(pwlarcpool) PwlArc( nsteps+1, newvert );
-
- arc->clearbezier();
- arc->clearside( );
-}
-
-
-/*-----------------------------------------------------------------------------
- * tessellateLinear - constuct a linear pwl arc and attach it to an Arc
- *-----------------------------------------------------------------------------
- */
-
-void
-ArcTessellator::tessellateLinear( Arc *arc, REAL geo_stepsize, REAL arc_stepsize, int isrational )
-{
- assert( arc->pwlArc == NULL );
- REAL s1, s2, t1, t2;
-
- //we don't need to scale by arc_stepsize if the trim curve
- //is piecewise linear. Reason: In pwl_right, pwl_left, pwl_top, pwl_left,
- //and pwl, the nsteps is computed by deltaU (or V) /stepsize.
- //The quantity deltaU/arc_stepsize doesn't have any meaning. And
- //it causes problems: see bug 517641
- REAL stepsize = geo_stepsize; /* * arc_stepsize*/;
-
- BezierArc *b = arc->bezierArc;
-
- if( isrational ) {
- s1 = b->cpts[0] / b->cpts[2];
- t1 = b->cpts[1] / b->cpts[2];
- s2 = b->cpts[b->stride+0] / b->cpts[b->stride+2];
- t2 = b->cpts[b->stride+1] / b->cpts[b->stride+2];
- } else {
- s1 = b->cpts[0];
- t1 = b->cpts[1];
- s2 = b->cpts[b->stride+0];
- t2 = b->cpts[b->stride+1];
- }
- if( s1 == s2 )
- if( t1 < t2 )
- pwl_right( arc, s1, t1, t2, stepsize );
- else
- pwl_left( arc, s1, t1, t2, stepsize );
- else if( t1 == t2 )
- if( s1 < s2 )
- pwl_bottom( arc, t1, s1, s2, stepsize );
- else
- pwl_top( arc, t1, s1, s2, stepsize );
- else
- pwl( arc, s1, s2, t1, t2, stepsize );
-}
-
-/*-----------------------------------------------------------------------------
- * tessellateNonlinear - constuct a nonlinear pwl arc and attach it to an Arc
- *-----------------------------------------------------------------------------
- */
-
-void
-ArcTessellator::tessellateNonlinear( Arc *arc, REAL geo_stepsize, REAL arc_stepsize, int isrational )
-{
- assert( arc->pwlArc == NULL );
-
- REAL stepsize = geo_stepsize * arc_stepsize;
-
- BezierArc *bezierArc = arc->bezierArc;
-
- REAL size; //bounding box size of the curve in UV
- {
- int i,j;
- REAL min_u, min_v, max_u,max_v;
- min_u = max_u = bezierArc->cpts[0];
- min_v = max_v = bezierArc->cpts[1];
- for(i=1, j=bezierArc->stride; i<bezierArc->order; i++, j+= bezierArc->stride)
- {
- if(bezierArc->cpts[j] < min_u)
- min_u = bezierArc->cpts[j];
- if(bezierArc->cpts[j] > max_u)
- max_u = bezierArc->cpts[j];
- if(bezierArc->cpts[j+1] < min_v)
- min_v = bezierArc->cpts[j+1];
- if(bezierArc->cpts[j+1] > max_v)
- max_v = bezierArc->cpts[j+1];
- }
-
- size = max_u - min_u;
- if(size < max_v - min_v)
- size = max_v - min_v;
- }
-
- /*int nsteps = 1 + (int) (1.0/stepsize);*/
-
- int nsteps = (int) (size/stepsize);
- if(nsteps <=0)
- nsteps=1;
-
- TrimVertex *vert = trimvertexpool.get( nsteps+1 );
- REAL dp = 1.0/nsteps;
-
-
- arc->pwlArc = new(pwlarcpool) PwlArc();
- arc->pwlArc->pts = vert;
-
- if( isrational ) {
- REAL pow_u[MAXORDER], pow_v[MAXORDER], pow_w[MAXORDER];
- trim_power_coeffs( bezierArc, pow_u, 0 );
- trim_power_coeffs( bezierArc, pow_v, 1 );
- trim_power_coeffs( bezierArc, pow_w, 2 );
-
- /* compute first point exactly */
- REAL *b = bezierArc->cpts;
- vert->param[0] = b[0]/b[2];
- vert->param[1] = b[1]/b[2];
-
- /* strength reduction on p = dp * step would introduce error */
- int step;
-#ifndef NOELIMINATION
- int ocanremove = 0;
-#endif
- register long order = bezierArc->order;
- for( step=1, ++vert; step<nsteps; step++, vert++ ) {
- register REAL p = dp * step;
- register REAL u = pow_u[0];
- register REAL v = pow_v[0];
- register REAL w = pow_w[0];
- for( register int i = 1; i < order; i++ ) {
- u = u * p + pow_u[i];
- v = v * p + pow_v[i];
- w = w * p + pow_w[i];
- }
- vert->param[0] = u/w;
- vert->param[1] = v/w;
-#ifndef NOELIMINATION
- REAL ds = glu_abs(vert[0].param[0] - vert[-1].param[0]);
- REAL dt = glu_abs(vert[0].param[1] - vert[-1].param[1]);
- int canremove = (ds<geo_stepsize && dt<geo_stepsize) ? 1 : 0;
- REAL ods=0.0, odt=0.0;
-
- if( ocanremove && canremove ) {
- REAL nds = ds + ods;
- REAL ndt = dt + odt;
- if( nds<geo_stepsize && ndt<geo_stepsize ) {
- // remove previous point
- --vert;
- vert[0].param[0] = vert[1].param[0];
- vert[0].param[1] = vert[1].param[1];
- ods = nds;
- odt = ndt;
- ocanremove = 1;
- } else {
- ocanremove = canremove;
- ods = ds;
- odt = dt;
- }
- } else {
- ocanremove = canremove;
- ods = ds;
- odt = dt;
- }
-#endif
- }
-
- /* compute last point exactly */
- b += (order - 1) * bezierArc->stride;
- vert->param[0] = b[0]/b[2];
- vert->param[1] = b[1]/b[2];
-
- } else {
- REAL pow_u[MAXORDER], pow_v[MAXORDER];
- trim_power_coeffs( bezierArc, pow_u, 0 );
- trim_power_coeffs( bezierArc, pow_v, 1 );
-
- /* compute first point exactly */
- REAL *b = bezierArc->cpts;
- vert->param[0] = b[0];
- vert->param[1] = b[1];
-
- /* strength reduction on p = dp * step would introduce error */
- int step;
-#ifndef NOELIMINATION
- int ocanremove = 0;
-#endif
- register long order = bezierArc->order;
- for( step=1, ++vert; step<nsteps; step++, vert++ ) {
- register REAL p = dp * step;
- register REAL u = pow_u[0];
- register REAL v = pow_v[0];
- for( register int i = 1; i < bezierArc->order; i++ ) {
- u = u * p + pow_u[i];
- v = v * p + pow_v[i];
- }
- vert->param[0] = u;
- vert->param[1] = v;
-#ifndef NOELIMINATION
- REAL ds = glu_abs(vert[0].param[0] - vert[-1].param[0]);
- REAL dt = glu_abs(vert[0].param[1] - vert[-1].param[1]);
- int canremove = (ds<geo_stepsize && dt<geo_stepsize) ? 1 : 0;
- REAL ods=0.0, odt=0.0;
-
- if( ocanremove && canremove ) {
- REAL nds = ds + ods;
- REAL ndt = dt + odt;
- if( nds<geo_stepsize && ndt<geo_stepsize ) {
- // remove previous point
- --vert;
- vert[0].param[0] = vert[1].param[0];
- vert[0].param[1] = vert[1].param[1];
- ods = nds;
- odt = ndt;
- ocanremove = 1;
- } else {
- ocanremove = canremove;
- ods = ds;
- odt = dt;
- }
- } else {
- ocanremove = canremove;
- ods = ds;
- odt = dt;
- }
-#endif
- }
-
- /* compute last point exactly */
- b += (order - 1) * bezierArc->stride;
- vert->param[0] = b[0];
- vert->param[1] = b[1];
- }
- arc->pwlArc->npts = vert - arc->pwlArc->pts + 1;
-/*
- for( TrimVertex *vt=pwlArc->pts; vt != vert-1; vt++ ) {
- if( tooclose( vt[0].param[0], vt[1].param[0] ) )
- vt[1].param[0] = vt[0].param[0];
- if( tooclose( vt[0].param[1], vt[1].param[1] ) )
- vt[1].param[1] = vt[0].param[1];
- }
-*/
-}
-
-const REAL ArcTessellator::gl_Bernstein[][MAXORDER][MAXORDER] = {
- {
- {1, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 }
- },
- {
- {-1, 1, 0, 0, 0, 0, 0, 0 },
- {1, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 }
- },
- {
- {1, -2, 1, 0, 0, 0, 0, 0 },
- {-2, 2, 0, 0, 0, 0, 0, 0 },
- {1, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 }
- },
- {
- {-1, 3, -3, 1, 0, 0, 0, 0 },
- {3, -6, 3, 0, 0, 0, 0, 0 },
- {-3, 3, 0, 0, 0, 0, 0, 0 },
- {1, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 }
- },
- {
- {1, -4, 6, -4, 1, 0, 0, 0 },
- {-4, 12, -12, 4, 0, 0, 0, 0 },
- {6, -12, 6, 0, 0, 0, 0, 0 },
- {-4, 4, 0, 0, 0, 0, 0, 0 },
- {1, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 }
- },
- {
- {-1, 5, -10, 10, -5, 1, 0, 0 },
- {5, -20, 30, -20, 5, 0, 0, 0 },
- {-10, 30, -30, 10, 0, 0, 0, 0 },
- {10, -20, 10, 0, 0, 0, 0, 0 },
- {-5, 5, 0, 0, 0, 0, 0, 0 },
- {1, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 }
- },
- {
- {1, -6, 15, -20, 15, -6, 1, 0 },
- {-6, 30, -60, 60, -30, 6, 0, 0 },
- {15, -60, 90, -60, 15, 0, 0, 0 },
- {-20, 60, -60, 20, 0, 0, 0, 0 },
- {15, -30, 15, 0, 0, 0, 0, 0 },
- {-6, 6, 0, 0, 0, 0, 0, 0 },
- {1, 0, 0, 0, 0, 0, 0, 0 },
- {0, 0, 0, 0, 0, 0, 0, 0 }
- },
- {
- {-1, 7, -21, 35, -35, 21, -7, 1 },
- {7, -42, 105, -140, 105, -42, 7, 0 },
- {-21, 105, -210, 210, -105, 21, 0, 0 },
- {35, -140, 210, -140, 35, 0, 0, 0 },
- {-35, 105, -105, 35, 0, 0, 0, 0 },
- {21, -42, 21, 0, 0, 0, 0, 0 },
- {-7, 7, 0, 0, 0, 0, 0, 0 },
- {1, 0, 0, 0, 0, 0, 0, 0 }
- }};
-
-
-/*-----------------------------------------------------------------------------
- * trim_power_coeffs - compute power basis coefficients from bezier coeffients
- *-----------------------------------------------------------------------------
- */
-void
-ArcTessellator::trim_power_coeffs( BezierArc *bez_arc, REAL *p, int coord )
-{
- register int stride = bez_arc->stride;
- register int order = bez_arc->order;
- register REAL *base = bez_arc->cpts + coord;
-
- REAL const (*mat)[MAXORDER][MAXORDER] = &gl_Bernstein[order-1];
- REAL const (*lrow)[MAXORDER] = &(*mat)[order];
-
- /* WIN32 didn't like the following line within the for-loop */
- REAL const (*row)[MAXORDER] = &(*mat)[0];
- for( ; row != lrow; row++ ) {
- register REAL s = 0.0;
- register REAL *point = base;
- register REAL const *mlast = *row + order;
- for( REAL const *m = *row; m != mlast; m++, point += stride )
- s += *(m) * (*point);
- *(p++) = s;
- }
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * arctess.h
- *
- */
-
-#ifndef __gluarctess_h_
-#define __gluarctess_h_
-
-#include "defines.h"
-#include "types.h"
-#include "arc.h"
-
-struct BezierArc;
-class Pool;
-class TrimVertexPool;
-
-class ArcTessellator {
-public:
- ArcTessellator( TrimVertexPool&, Pool& );
- ~ArcTessellator( void );
- void bezier( Arc_ptr, REAL, REAL, REAL, REAL );
- void pwl( Arc_ptr, REAL, REAL, REAL, REAL, REAL );
- void pwl_left( Arc_ptr, REAL, REAL, REAL, REAL );
- void pwl_right( Arc_ptr, REAL, REAL, REAL, REAL );
- void pwl_top( Arc_ptr, REAL, REAL, REAL, REAL );
- void pwl_bottom( Arc_ptr, REAL, REAL, REAL, REAL );
- void tessellateLinear( Arc_ptr, REAL, REAL, int );
- void tessellateNonlinear( Arc_ptr, REAL, REAL, int );
-private:
- static const REAL gl_Bernstein[][MAXORDER][MAXORDER];
- Pool& pwlarcpool;
- TrimVertexPool& trimvertexpool;
- static void trim_power_coeffs( BezierArc *, REAL[MAXORDER], int );
-};
-
-#endif /* __gluarctess_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * backend.c++
- *
- */
-
-/* Bezier surface backend
- - interprets display mode (wireframe,shaded,...)
-*/
-#include <stdio.h>
-#include "glimports.h"
-#include "mystdio.h"
-#include "backend.h"
-#include "basiccrveval.h"
-#include "basicsurfeval.h"
-
-#define NOWIREFRAME
-
-
-/*-------------------------------------------------------------------------
- * bgnsurf - preamble to surface definition and evaluations
- *-------------------------------------------------------------------------
- */
-void
-Backend::bgnsurf( int wiretris, int wirequads, long nuid )
-{
-/*#ifndef NOWIREFRAME*/ //need this for old version
- wireframetris = wiretris;
- wireframequads = wirequads;
-/*#endif*/
-
- /*in the spec, GLU_DISPLAY_MODE is either
- * GLU_FILL
- * GLU_OUTLINE_POLY
- * GLU_OUTLINE_PATCH.
- *In fact, GLU_FLL is has the same effect as
- * set GL_FRONT_AND_BACK to be GL_FILL
- * and GLU_OUTLINE_POLY is the same as set
- * GL_FRONT_AND_BACK to be GL_LINE
- *It is more efficient to do this once at the beginning of
- *each surface than to do it for each primitive.
- * The internal has more options: outline_triangle and outline_quad
- *can be seperated. But since this is not in spec, and more importantly,
- *this is not so useful, so we don't need to keep this option.
- */
-
- surfaceEvaluator.bgnmap2f( nuid );
-
- if(wiretris)
- surfaceEvaluator.polymode(N_MESHLINE);
- else
- surfaceEvaluator.polymode(N_MESHFILL);
-}
-
-void
-Backend::patch( REAL ulo, REAL uhi, REAL vlo, REAL vhi )
-{
- surfaceEvaluator.domain2f( ulo, uhi, vlo, vhi );
-}
-
-void
-Backend::surfbbox( long type, REAL *from, REAL *to )
-{
- surfaceEvaluator.range2f( type, from, to );
-}
-
-/*-------------------------------------------------------------------------
- * surfpts - pass a desription of a surface map
- *-------------------------------------------------------------------------
- */
-void
-Backend::surfpts(
- long type, /* geometry, color, texture, normal */
- REAL *pts, /* control points */
- long ustride, /* distance to next point in u direction */
- long vstride, /* distance to next point in v direction */
- int uorder, /* u parametric order */
- int vorder, /* v parametric order */
- REAL ulo, /* u lower bound */
- REAL uhi, /* u upper bound */
- REAL vlo, /* v lower bound */
- REAL vhi ) /* v upper bound */
-{
- surfaceEvaluator.map2f( type,ulo,uhi,ustride,uorder,vlo,vhi,vstride,vorder,pts );
- surfaceEvaluator.enable( type );
-}
-
-/*-------------------------------------------------------------------------
- * surfgrid - define a lattice of points with origin and offset
- *-------------------------------------------------------------------------
- */
-void
-Backend::surfgrid( REAL u0, REAL u1, long nu, REAL v0, REAL v1, long nv )
-{
- surfaceEvaluator.mapgrid2f( nu, u0, u1, nv, v0, v1 );
-}
-
-/*-------------------------------------------------------------------------
- * surfmesh - evaluate a mesh of points on lattice
- *-------------------------------------------------------------------------
- */
-void
-Backend::surfmesh( long u, long v, long n, long m )
-{
-#ifndef NOWIREFRAME
- if( wireframequads ) {
- long v0, v1;
- long u0f = u, u1f = u+n;
- long v0f = v, v1f = v+m;
- long parity = (u & 1);
-
- for( v0 = v0f, v1 = v0f++ ; v0<v1f; v0 = v1, v1++ ) {
- surfaceEvaluator.bgnline();
- for( long u = u0f; u<=u1f; u++ ) {
- if( parity ) {
- surfaceEvaluator.evalpoint2i( u, v0 );
- surfaceEvaluator.evalpoint2i( u, v1 );
- } else {
- surfaceEvaluator.evalpoint2i( u, v1 );
- surfaceEvaluator.evalpoint2i( u, v0 );
- }
- parity = 1 - parity;
- }
- surfaceEvaluator.endline();
- }
- } else {
- surfaceEvaluator.mapmesh2f( N_MESHFILL, u, u+n, v, v+m );
- }
-#else
- if( wireframequads ) {
-
- surfaceEvaluator.mapmesh2f( N_MESHLINE, u, u+n, v, v+m );
- } else {
-
- surfaceEvaluator.mapmesh2f( N_MESHFILL, u, u+n, v, v+m );
- }
-#endif
-}
-
-/*-------------------------------------------------------------------------
- * endsurf - postamble to surface
- *-------------------------------------------------------------------------
- */
-void
-Backend::endsurf( void )
-{
- surfaceEvaluator.endmap2f();
-}
-
-/***************************************/
-void
-Backend::bgntfan( void )
-{
- surfaceEvaluator.bgntfan();
-/*
- if(wireframetris)
- surfaceEvaluator.polymode( N_MESHLINE );
- else
- surfaceEvaluator.polymode( N_MESHFILL );
-*/
-}
-
-void
-Backend::endtfan( void )
-{
- surfaceEvaluator.endtfan();
-}
-
-void
-Backend::bgnqstrip( void )
-{
- surfaceEvaluator.bgnqstrip();
-/*
- if(wireframequads)
- surfaceEvaluator.polymode( N_MESHLINE );
- else
- surfaceEvaluator.polymode( N_MESHFILL );
-*/
-}
-
-void
-Backend::endqstrip( void )
-{
- surfaceEvaluator.endqstrip();
-}
-
-void
-Backend::evalUStrip(int n_upper, REAL v_upper, REAL* upper_val,
- int n_lower, REAL v_lower, REAL* lower_val
- )
-{
- surfaceEvaluator.evalUStrip(n_upper, v_upper, upper_val,
- n_lower, v_lower, lower_val);
-}
-
-void
-Backend::evalVStrip(int n_left, REAL u_left, REAL* left_val,
- int n_right, REAL u_right, REAL* right_val
- )
-{
- surfaceEvaluator.evalVStrip(n_left, u_left, left_val,
- n_right, u_right, right_val);
-}
-
-/***************************************/
-
-
-/*-------------------------------------------------------------------------
- * bgntmesh - preamble to a triangle mesh
- *-------------------------------------------------------------------------
- */
-void
-Backend::bgntmesh( const char * )
-{
-#ifndef NOWIREFRAME
-
- meshindex = 0; /* I think these need to be initialized to zero */
- npts = 0;
-
- if( !wireframetris ) {
- surfaceEvaluator.bgntmesh();
- }
-#else
-
- if( wireframetris ) {
- surfaceEvaluator.bgntmesh();
- surfaceEvaluator.polymode( N_MESHLINE );
- } else {
- surfaceEvaluator.bgntmesh();
- surfaceEvaluator.polymode( N_MESHFILL );
- }
-#endif
-}
-
-void
-Backend::tmeshvert( GridTrimVertex *v )
-{
- if( v->isGridVert() ) {
- tmeshvert( v->g );
- } else {
- tmeshvert( v->t );
- }
-}
-
-void
-Backend::tmeshvertNOGE(TrimVertex *t)
-{
-// surfaceEvaluator.inDoEvalCoord2NOGE( t->param[0], t->param[1], temp, ttt);
-#ifdef USE_OPTTT
- surfaceEvaluator.inDoEvalCoord2NOGE( t->param[0], t->param[1], t->cache_point, t->cache_normal);
-#endif
-}
-
-//opt for a line with the same u.
-void
-Backend::tmeshvertNOGE_BU(TrimVertex *t)
-{
-#ifdef USE_OPTTT
- surfaceEvaluator.inDoEvalCoord2NOGE_BU( t->param[0], t->param[1], t->cache_point, t->cache_normal);
-#endif
-}
-
-//opt for a line with the same v.
-void
-Backend::tmeshvertNOGE_BV(TrimVertex *t)
-{
-#ifdef USE_OPTTT
- surfaceEvaluator.inDoEvalCoord2NOGE_BV( t->param[0], t->param[1], t->cache_point, t->cache_normal);
-#endif
-}
-
-void
-Backend::preEvaluateBU(REAL u)
-{
- surfaceEvaluator.inPreEvaluateBU_intfac(u);
-}
-
-void
-Backend::preEvaluateBV(REAL v)
-{
- surfaceEvaluator.inPreEvaluateBV_intfac(v);
-}
-
-
-/*-------------------------------------------------------------------------
- * tmeshvert - evaluate a point on a triangle mesh
- *-------------------------------------------------------------------------
- */
-void
-Backend::tmeshvert( TrimVertex *t )
-{
-
-#ifndef NOWIREFRAME
- const long nuid = t->nuid;
-#endif
- const REAL u = t->param[0];
- const REAL v = t->param[1];
-
-#ifndef NOWIREFRAME
- npts++;
- if( wireframetris ) {
- if( npts >= 3 ) {
- surfaceEvaluator.bgnclosedline();
- if( mesh[0][2] == 0 )
- surfaceEvaluator.evalcoord2f( mesh[0][3], mesh[0][0], mesh[0][1] );
- else
- surfaceEvaluator.evalpoint2i( (long) mesh[0][0], (long) mesh[0][1] );
- if( mesh[1][2] == 0 )
- surfaceEvaluator.evalcoord2f( mesh[1][3], mesh[1][0], mesh[1][1] );
- else
- surfaceEvaluator.evalpoint2i( (long) mesh[1][0], (long) mesh[1][1] );
- surfaceEvaluator.evalcoord2f( nuid, u, v );
- surfaceEvaluator.endclosedline();
- }
- mesh[meshindex][0] = u;
- mesh[meshindex][1] = v;
- mesh[meshindex][2] = 0;
- mesh[meshindex][3] = nuid;
- meshindex = (meshindex+1) % 2;
- } else {
- surfaceEvaluator.evalcoord2f( nuid, u, v );
- }
-#else
-
- surfaceEvaluator.evalcoord2f( 0, u, v );
-//for uninitial memory read surfaceEvaluator.evalcoord2f( nuid, u, v );
-#endif
-}
-
-//the same as tmeshvert(trimvertex), for efficiency purpose
-void
-Backend::tmeshvert( REAL u, REAL v )
-{
-#ifndef NOWIREFRAME
- const long nuid = 0;
-
- npts++;
- if( wireframetris ) {
- if( npts >= 3 ) {
- surfaceEvaluator.bgnclosedline();
- if( mesh[0][2] == 0 )
- surfaceEvaluator.evalcoord2f( mesh[0][3], mesh[0][0], mesh[0][1] );
- else
- surfaceEvaluator.evalpoint2i( (long) mesh[0][0], (long) mesh[0][1] );
- if( mesh[1][2] == 0 )
- surfaceEvaluator.evalcoord2f( mesh[1][3], mesh[1][0], mesh[1][1] );
- else
- surfaceEvaluator.evalpoint2i( (long) mesh[1][0], (long) mesh[1][1] );
- surfaceEvaluator.evalcoord2f( nuid, u, v );
- surfaceEvaluator.endclosedline();
- }
- mesh[meshindex][0] = u;
- mesh[meshindex][1] = v;
- mesh[meshindex][2] = 0;
- mesh[meshindex][3] = nuid;
- meshindex = (meshindex+1) % 2;
- } else {
- surfaceEvaluator.evalcoord2f( nuid, u, v );
- }
-#else
-
- surfaceEvaluator.evalcoord2f( 0, u, v );
-#endif
-}
-
-/*-------------------------------------------------------------------------
- * tmeshvert - evaluate a grid point of a triangle mesh
- *-------------------------------------------------------------------------
- */
-void
-Backend::tmeshvert( GridVertex *g )
-{
- const long u = g->gparam[0];
- const long v = g->gparam[1];
-
-#ifndef NOWIREFRAME
- npts++;
- if( wireframetris ) {
- if( npts >= 3 ) {
- surfaceEvaluator.bgnclosedline();
- if( mesh[0][2] == 0 )
- surfaceEvaluator.evalcoord2f( (long) mesh[0][3], mesh[0][0], mesh[0][1] );
- else
- surfaceEvaluator.evalpoint2i( (long) mesh[0][0], (long) mesh[0][1] );
- if( mesh[1][2] == 0 )
- surfaceEvaluator.evalcoord2f( (long) mesh[1][3], mesh[1][0], mesh[1][1] );
- else
- surfaceEvaluator.evalpoint2i( (long) mesh[1][0], (long) mesh[1][1] );
- surfaceEvaluator.evalpoint2i( u, v );
- surfaceEvaluator.endclosedline();
- }
- mesh[meshindex][0] = u;
- mesh[meshindex][1] = v;
- mesh[meshindex][2] = 1;
- meshindex = (meshindex+1) % 2;
- } else {
- surfaceEvaluator.evalpoint2i( u, v );
- }
-#else
- surfaceEvaluator.evalpoint2i( u, v );
-#endif
-}
-
-/*-------------------------------------------------------------------------
- * swaptmesh - perform a swap of the triangle mesh pointers
- *-------------------------------------------------------------------------
- */
-void
-Backend::swaptmesh( void )
-{
-#ifndef NOWIREFRAME
- if( wireframetris ) {
- meshindex = 1 - meshindex;
- } else {
- surfaceEvaluator.swaptmesh();
- }
-#else
- surfaceEvaluator.swaptmesh();
-#endif
-}
-
-/*-------------------------------------------------------------------------
- * endtmesh - postamble to triangle mesh
- *-------------------------------------------------------------------------
- */
-void
-Backend::endtmesh( void )
-{
-#ifndef NOWIREFRAME
- if( ! wireframetris )
- surfaceEvaluator.endtmesh();
-#else
- surfaceEvaluator.endtmesh();
-/* surfaceEvaluator.polymode( N_MESHFILL );*/
-#endif
-}
-
-
-/*-------------------------------------------------------------------------
- * bgnoutline - preamble to outlined rendering
- *-------------------------------------------------------------------------
- */
-void
-Backend::bgnoutline( void )
-{
- surfaceEvaluator.bgnline();
-}
-
-/*-------------------------------------------------------------------------
- * linevert - evaluate a point on an outlined contour
- *-------------------------------------------------------------------------
- */
-void
-Backend::linevert( TrimVertex *t )
-{
- surfaceEvaluator.evalcoord2f( t->nuid, t->param[0], t->param[1] );
-}
-
-/*-------------------------------------------------------------------------
- * linevert - evaluate a grid point of an outlined contour
- *-------------------------------------------------------------------------
- */
-void
-Backend::linevert( GridVertex *g )
-{
- surfaceEvaluator.evalpoint2i( g->gparam[0], g->gparam[1] );
-}
-
-/*-------------------------------------------------------------------------
- * endoutline - postamble to outlined rendering
- *-------------------------------------------------------------------------
- */
-void
-Backend::endoutline( void )
-{
- surfaceEvaluator.endline();
-}
-
-/*-------------------------------------------------------------------------
- * triangle - output a triangle
- *-------------------------------------------------------------------------
- */
-void
-Backend::triangle( TrimVertex *a, TrimVertex *b, TrimVertex *c )
-{
-/* bgntmesh( "spittriangle" );*/
- bgntfan();
- tmeshvert( a );
- tmeshvert( b );
- tmeshvert( c );
- endtfan();
-/* endtmesh();*/
-}
-
-void
-Backend::bgncurv( void )
-{
- curveEvaluator.bgnmap1f( 0 );
-}
-
-void
-Backend::segment( REAL ulo, REAL uhi )
-{
- curveEvaluator.domain1f( ulo, uhi );
-}
-
-void
-Backend::curvpts(
- long type, /* geometry, color, texture, normal */
- REAL *pts, /* control points */
- long stride, /* distance to next point */
- int order, /* parametric order */
- REAL ulo, /* lower parametric bound */
- REAL uhi ) /* upper parametric bound */
-
-{
- curveEvaluator.map1f( type, ulo, uhi, stride, order, pts );
- curveEvaluator.enable( type );
-}
-
-void
-Backend::curvgrid( REAL u0, REAL u1, long nu )
-{
- curveEvaluator.mapgrid1f( nu, u0, u1 );
-}
-
-void
-Backend::curvmesh( long from, long n )
-{
- curveEvaluator.mapmesh1f( N_MESHFILL, from, from+n );
-}
-
-void
-Backend::curvpt(REAL u)
-{
- curveEvaluator.evalcoord1f( 0, u );
-}
-
-void
-Backend::bgnline( void )
-{
- curveEvaluator.bgnline();
-}
-
-void
-Backend::endline( void )
-{
- curveEvaluator.endline();
-}
-
-void
-Backend::endcurv( void )
-{
- curveEvaluator.endmap1f();
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * backend.h
- *
- */
-
-#ifndef __glubackend_h_
-#define __glubackend_h_
-
-#include "trimvertex.h"
-#include "gridvertex.h"
-#include "gridtrimvertex.h"
-
-class BasicCurveEvaluator;
-class BasicSurfaceEvaluator;
-
-class Backend {
-private:
- BasicCurveEvaluator& curveEvaluator;
- BasicSurfaceEvaluator& surfaceEvaluator;
-public:
- Backend( BasicCurveEvaluator &c, BasicSurfaceEvaluator& e )
- : curveEvaluator(c), surfaceEvaluator(e) {}
-
- /* surface backend routines */
- void bgnsurf( int, int, long );
- void patch( REAL, REAL, REAL, REAL );
- void surfpts( long, REAL *, long, long, int, int,
- REAL, REAL, REAL, REAL );
- void surfbbox( long, REAL *, REAL * );
- void surfgrid( REAL, REAL, long, REAL, REAL, long );
- void surfmesh( long, long, long, long );
- void bgntmesh( const char * );
- void endtmesh( void );
- void swaptmesh( void );
- void tmeshvert( GridTrimVertex * );
- void tmeshvert( TrimVertex * );
- void tmeshvert( GridVertex * );
- void tmeshvert( REAL u, REAL v );
- void linevert( TrimVertex * );
- void linevert( GridVertex * );
- void bgnoutline( void );
- void endoutline( void );
- void endsurf( void );
- void triangle( TrimVertex*, TrimVertex*, TrimVertex* );
-
- void bgntfan();
- void endtfan();
- void bgnqstrip();
- void endqstrip();
- void evalUStrip(int n_upper, REAL v_upper, REAL* upper_val,
- int n_lower, REAL v_lower, REAL* lower_val
- );
- void evalVStrip(int n_left, REAL u_left, REAL* left_val,
- int n_right, REAL v_right, REAL* right_val
- );
- void tmeshvertNOGE(TrimVertex *t);
- void tmeshvertNOGE_BU(TrimVertex *t);
- void tmeshvertNOGE_BV(TrimVertex *t);
- void preEvaluateBU(REAL u);
- void preEvaluateBV(REAL v);
-
-
- /* curve backend routines */
- void bgncurv( void );
- void segment( REAL, REAL );
- void curvpts( long, REAL *, long, int, REAL, REAL );
- void curvgrid( REAL, REAL, long );
- void curvmesh( long, long );
- void curvpt( REAL );
- void bgnline( void );
- void endline( void );
- void endcurv( void );
-private:
-#ifndef NOWIREFRAME
- int wireframetris;
- int wireframequads;
- int npts;
- REAL mesh[3][4];
- int meshindex;
-#endif
-};
-
-#endif /* __glubackend_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * basiccrveval.c++
- *
- */
-
-#include "mystdio.h"
-#include "types.h"
-#include "basiccrveval.h"
-
-void
-BasicCurveEvaluator::domain1f( REAL, REAL )
-{
-#ifndef NDEBUG
- _glu_dprintf( "domain1f\n" );
-#endif
-}
-
-void
-BasicCurveEvaluator::range1f( long , REAL *, REAL * )
-{
-#ifndef NDEBUG
- _glu_dprintf( "range1f\n" );
-#endif
-}
-
-void
-BasicCurveEvaluator::enable( long )
-{
-#ifndef NDEBUG
- _glu_dprintf( "enable\n" );
-#endif
-}
-
-void
-BasicCurveEvaluator::disable( long )
-{
-#ifndef NDEBUG
- _glu_dprintf( "disable\n" );
-#endif
-}
-
-void
-BasicCurveEvaluator::bgnmap1f( long )
-{
-#ifndef NDEBUG
- _glu_dprintf( "bgnmap1f\n" );
-#endif
-}
-
-void
-BasicCurveEvaluator::map1f( long, REAL, REAL, long, long, REAL * )
-{
-#ifndef NDEBUG
- _glu_dprintf( "map1f\n" );
-#endif
-}
-
-void
-BasicCurveEvaluator::mapgrid1f( long, REAL, REAL )
-{
-#ifndef NDEBUG
- _glu_dprintf( "mapgrid1f\n" );
-#endif
-}
-
-void
-BasicCurveEvaluator::mapmesh1f( long, long, long )
-{
-#ifndef NDEBUG
- _glu_dprintf( "mapmesh1f\n" );
-#endif
-}
-
-void
-BasicCurveEvaluator::evalcoord1f( long, REAL )
-{
-#ifndef NDEBUG
- _glu_dprintf( "evalcoord1f\n" );
-#endif
-}
-
-void
-BasicCurveEvaluator::endmap1f( void )
-{
-#ifndef NDEBUG
- _glu_dprintf( "endmap1f\n" );
-#endif
-}
-
-void
-BasicCurveEvaluator::bgnline( void )
-{
-#ifndef NDEBUG
- _glu_dprintf( "bgnline\n" );
-#endif
-}
-
-void
-BasicCurveEvaluator::endline( void )
-{
-#ifndef NDEBUG
- _glu_dprintf( "endline\n" );
-#endif
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * basiccurveeval.h
- *
- */
-
-#ifndef __glubasiccrveval_h_
-#define __glubasiccrveval_h_
-
-#include "types.h"
-#include "displaymode.h"
-#include "cachingeval.h"
-
-class BasicCurveEvaluator : public CachingEvaluator {
-public:
- virtual ~BasicCurveEvaluator() { /* silence warning*/ }
- virtual void domain1f( REAL, REAL );
- virtual void range1f( long, REAL *, REAL * );
-
- virtual void enable( long );
- virtual void disable( long );
- virtual void bgnmap1f( long );
- virtual void map1f( long, REAL, REAL, long, long, REAL * );
- virtual void mapgrid1f( long, REAL, REAL );
- virtual void mapmesh1f( long, long, long );
- virtual void evalcoord1f( long, REAL );
- virtual void endmap1f( void );
-
- virtual void bgnline( void );
- virtual void endline( void );
-};
-
-#endif /* __glubasiccrveval_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * basicsurfaceevaluator.c++
- *
- */
-
-#include "mystdio.h"
-#include "types.h"
-#include "basicsurfeval.h"
-
-#ifdef __WATCOMC__
-#pragma warning 726 10
-#endif
-
-void
-BasicSurfaceEvaluator::domain2f( REAL, REAL, REAL, REAL )
-{
-#ifndef NDEBUG
- _glu_dprintf( "domain2f\n" );
-#endif
-}
-
-void
-BasicSurfaceEvaluator::polymode( long )
-{
-#ifndef NDEBUG
- _glu_dprintf( "polymode\n" );
-#endif
-}
-
-void
-BasicSurfaceEvaluator::range2f( long type, REAL *from, REAL *to )
-{
-#ifndef NDEBUG
- _glu_dprintf( "range2f type %ld, from (%g,%g), to (%g,%g)\n",
- type, from[0], from[1], to[0], to[1] );
-#endif
-}
-
-void
-BasicSurfaceEvaluator::enable( long )
-{
-#ifndef NDEBUG
- _glu_dprintf( "enable\n" );
-#endif
-}
-
-void
-BasicSurfaceEvaluator::disable( long )
-{
-#ifndef NDEBUG
- _glu_dprintf( "disable\n" );
-#endif
-}
-
-void
-BasicSurfaceEvaluator::bgnmap2f( long )
-{
-#ifndef NDEBUG
- _glu_dprintf( "bgnmap2f\n" );
-#endif
-}
-
-void
-BasicSurfaceEvaluator::endmap2f( void )
-{
-#ifndef NDEBUG
- _glu_dprintf( "endmap2f\n" );
-#endif
-}
-
-void
-BasicSurfaceEvaluator::map2f( long, REAL, REAL, long, long,
- REAL, REAL, long, long,
- REAL * )
-{
-#ifndef NDEBUG
- _glu_dprintf( "map2f\n" );
-#endif
-}
-
-void
-BasicSurfaceEvaluator::mapgrid2f( long, REAL, REAL, long, REAL, REAL )
-{
-#ifndef NDEBUG
- _glu_dprintf( "mapgrid2f\n" );
-#endif
-}
-
-void
-BasicSurfaceEvaluator::mapmesh2f( long, long, long, long, long )
-{
-#ifndef NDEBUG
- _glu_dprintf( "mapmesh2f\n" );
-#endif
-}
-
-void
-BasicSurfaceEvaluator::evalcoord2f( long, REAL, REAL )
-{
-#ifndef NDEBUG
- _glu_dprintf( "evalcoord2f\n" );
-#endif
-}
-
-void
-BasicSurfaceEvaluator::evalpoint2i( long, long )
-{
-#ifndef NDEBUG
- _glu_dprintf( "evalpoint2i\n" );
-#endif
-}
-
-void
-BasicSurfaceEvaluator::bgnline( void )
-{
-#ifndef NDEBUG
- _glu_dprintf( "bgnline\n" );
-#endif
-}
-
-void
-BasicSurfaceEvaluator::endline( void )
-{
-#ifndef NDEBUG
- _glu_dprintf( "endline\n" );
-#endif
-}
-
-void
-BasicSurfaceEvaluator::bgnclosedline( void )
-{
-#ifndef NDEBUG
- _glu_dprintf( "bgnclosedline\n" );
-#endif
-}
-
-void
-BasicSurfaceEvaluator::endclosedline( void )
-{
-#ifndef NDEBUG
- _glu_dprintf( "endclosedline\n" );
-#endif
-}
-
-void
-BasicSurfaceEvaluator::bgntfan( void )
-{
-#ifndef NDEBUG
- _glu_dprintf( "bgntfan\n" );
-#endif
-}
-
-void
-BasicSurfaceEvaluator::endtfan( void )
-{
-}
-
-
-void
-BasicSurfaceEvaluator::bgntmesh( void )
-{
-#ifndef NDEBUG
- _glu_dprintf( "bgntmesh\n" );
-#endif
-}
-
-void
-BasicSurfaceEvaluator::swaptmesh( void )
-{
-#ifndef NDEBUG
- _glu_dprintf( "swaptmesh\n" );
-#endif
-}
-
-void
-BasicSurfaceEvaluator::endtmesh( void )
-{
-#ifndef NDEBUG
- _glu_dprintf( "endtmesh\n" );
-#endif
-}
-
-void
-BasicSurfaceEvaluator::bgnqstrip( void )
-{
-#ifndef NDEBUG
- _glu_dprintf( "bgnqstrip\n" );
-#endif
-}
-
-void
-BasicSurfaceEvaluator::endqstrip( void )
-{
-#ifndef NDEBUG
- _glu_dprintf( "endqstrip\n" );
-#endif
-}
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * basicsurfeval.h
- *
- */
-
-#ifndef __glubasicsurfeval_h_
-#define __glubasicsurfeval_h_
-
-#include "types.h"
-#include "displaymode.h"
-#include "cachingeval.h"
-
-class BasicSurfaceEvaluator : public CachingEvaluator {
-public:
- virtual ~BasicSurfaceEvaluator() { /* silence warning*/ }
- virtual void range2f( long, REAL *, REAL * );
- virtual void domain2f( REAL, REAL, REAL, REAL );
-
- virtual void enable( long );
- virtual void disable( long );
- virtual void bgnmap2f( long );
- virtual void map2f( long, REAL, REAL, long, long,
- REAL, REAL, long, long,
- REAL * );
- virtual void mapgrid2f( long, REAL, REAL, long, REAL, REAL );
- virtual void mapmesh2f( long, long, long, long, long );
- virtual void evalcoord2f( long, REAL, REAL );
- virtual void evalpoint2i( long, long );
- virtual void endmap2f( void );
-
- virtual void polymode( long );
- virtual void bgnline( void );
- virtual void endline( void );
- virtual void bgnclosedline( void );
- virtual void endclosedline( void );
- virtual void bgntmesh( void );
- virtual void swaptmesh( void );
- virtual void endtmesh( void );
- virtual void bgnqstrip( void );
- virtual void endqstrip( void );
-
- virtual void bgntfan( void );
- virtual void endtfan( void );
-
- virtual void evalUStrip(int n_upper, REAL v_upper, REAL* upper_val,
- int n_lower, REAL v_lower, REAL* lower_val
- ) = 0;
-
- virtual void evalVStrip(int n_left, REAL u_left, REAL* left_val,
- int n_right, REAL u_right, REAL* right_val
- ) = 0;
- virtual void inDoEvalCoord2NOGE(REAL u, REAL v, REAL* ret_point, REAL* ret_normal) = 0;
- virtual void inDoEvalCoord2NOGE_BU(REAL u, REAL v, REAL* ret_point, REAL* ret_normal) = 0;
- virtual void inDoEvalCoord2NOGE_BV(REAL u, REAL v, REAL* ret_point, REAL* ret_normal) = 0;
- virtual void inPreEvaluateBV_intfac(REAL v ) = 0;
- virtual void inPreEvaluateBU_intfac(REAL u ) = 0;
-
-};
-
-#endif /* __glubasicsurfeval_h_ */
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * bezierarc.h
- *
- */
-
-#ifndef __glubezierarc_h
-#define __glubezierarc_h
-
-#include "myassert.h"
-
-class Mapdesc;
-
-struct BezierArc : public PooledObj { /* a bezier arc */
- REAL * cpts; /* control points of arc */
- int order; /* order of arc */
- int stride; /* REAL distance between points */
- long type; /* curve type */
- Mapdesc * mapdesc;
-};
-
-#endif /* __glubezierarc_h */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * bin.c++
- *
- */
-
-#include "glimports.h"
-#include "mystdio.h"
-#include "myassert.h"
-#include "bin.h"
-
-/*----------------------------------------------------------------------------
- * Constructor and destructor
- *----------------------------------------------------------------------------
- */
-Bin::Bin()
-{
- head = NULL;
- current = NULL;
-}
-
-Bin::~Bin()
-{
- assert( head == NULL);
-}
-
-/*----------------------------------------------------------------------------
- * remove_this_arc - remove given Arc_ptr from bin
- *----------------------------------------------------------------------------
- */
-
-void
-Bin::remove_this_arc( Arc_ptr arc )
-{
- Arc_ptr *j;
- for( j = &(head); (*j != 0) && (*j != arc); j = &((*j)->link) );
-
- if( *j != 0 ) {
- if( *j == current )
- current = (*j)->link;
- *j = (*j)->link;
- }
-}
-
-/*----------------------------------------------------------------------------
- * numarcs - count number of arcs in bin
- *----------------------------------------------------------------------------
- */
-
-int
-Bin::numarcs()
-{
- long count = 0;
- for( Arc_ptr jarc = firstarc(); jarc; jarc = nextarc() )
- count++;
- return count;
-}
-
-/*----------------------------------------------------------------------------
- * adopt - place an orphaned arcs into their new parents bin
- *----------------------------------------------------------------------------
- */
-
-void
-Bin::adopt()
-{
- markall();
-
- Arc_ptr orphan;
- while( (orphan = removearc()) != NULL ) {
- for( Arc_ptr parent = orphan->next; parent != orphan; parent = parent->next ) {
- if (! parent->ismarked() ) {
- orphan->link = parent->link;
- parent->link = orphan;
- orphan->clearmark();
- break;
- }
- }
- }
-}
-
-
-/*----------------------------------------------------------------------------
- * show - print out descriptions of the arcs in the bin
- *----------------------------------------------------------------------------
- */
-
-void
-Bin::show( const char *name )
-{
-#ifndef NDEBUG
- _glu_dprintf( "%s\n", name );
- for( Arc_ptr jarc = firstarc(); jarc; jarc = nextarc() )
- jarc->show( );
-#endif
-}
-
-
-
-/*----------------------------------------------------------------------------
- * markall - mark all arcs with an identifying tag
- *----------------------------------------------------------------------------
- */
-
-void
-Bin::markall()
-{
- for( Arc_ptr jarc=firstarc(); jarc; jarc=nextarc() )
- jarc->setmark();
-}
-
-/*----------------------------------------------------------------------------
- * listBezier - print out all arcs that are untessellated border arcs
- *----------------------------------------------------------------------------
- */
-
-void
-Bin::listBezier( void )
-{
- for( Arc_ptr jarc=firstarc(); jarc; jarc=nextarc() ) {
- if( jarc->isbezier( ) ) {
- assert( jarc->pwlArc->npts == 2 );
-#ifndef NDEBUG
- TrimVertex *pts = jarc->pwlArc->pts;
- REAL s1 = pts[0].param[0];
- REAL t1 = pts[0].param[1];
- REAL s2 = pts[1].param[0];
- REAL t2 = pts[1].param[1];
- _glu_dprintf( "arc (%g,%g) (%g,%g)\n", s1, t1, s2, t2 );
-#endif
- }
- }
-}
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * bin.h
- *
- */
-
-#ifndef __glubin_h_
-#define __glubin_h_
-
-#include "myassert.h"
-#include "arc.h"
-#include "defines.h"
-
-class Bin
-{ /* a linked list of jordan arcs */
-private:
- Arc_ptr head;/*first arc on list */
- Arc_ptr current; /* current arc on list */
-public:
- Bin();
- ~Bin();
- inline Arc_ptr firstarc( void );
- inline Arc_ptr nextarc( void );
- inline Arc_ptr removearc( void );
- inline int isnonempty( void ) { return (head ? 1 : 0); }
- inline void addarc( Arc_ptr );
- void remove_this_arc( Arc_ptr );
- int numarcs( void );
- void adopt( void );
- void markall( void );
- void show( const char * );
- void listBezier( void );
-};
-
-/*----------------------------------------------------------------------------
- * Bin::addarc - add an Arc_ptr to head of linked list of Arc_ptr
- *----------------------------------------------------------------------------
- */
-
-inline void
-Bin::addarc( Arc_ptr jarc )
-{
- jarc->link = head;
- head = jarc;
-}
-
-/*----------------------------------------------------------------------------
- * Bin::removearc - remove first Arc_ptr from bin
- *----------------------------------------------------------------------------
- */
-
-inline Arc_ptr
-Bin::removearc( void )
-{
- Arc_ptr jarc = head;
-
- if( jarc ) head = jarc->link;
- return jarc;
-}
-
-
-/*----------------------------------------------------------------------------
- * BinIter::nextarc - return current arc in bin and advance pointer to next arc
- *----------------------------------------------------------------------------
- */
-
-inline Arc_ptr
-Bin::nextarc( void )
-{
- Arc_ptr jarc = current;
-
-#ifdef DEBUG
- assert( jarc->check() != 0 );
-#endif
-
- if( jarc ) current = jarc->link;
- return jarc;
-}
-
-/*----------------------------------------------------------------------------
- * BinIter::firstarc - set current arc to first arc of bin advance to next arc
- *----------------------------------------------------------------------------
- */
-
-inline Arc_ptr
-Bin::firstarc( void )
-{
- current = head;
- return nextarc( );
-}
-
-#endif /* __glubin_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * bufpool.c++
- *
- */
-
-#include "glimports.h"
-#include "myassert.h"
-#include "bufpool.h"
-
-
-/*-----------------------------------------------------------------------------
- * Pool - allocate a new pool of buffers
- *-----------------------------------------------------------------------------
- */
-Pool::Pool( int _buffersize, int initpoolsize, const char *n )
-{
- if((unsigned)_buffersize < sizeof(Buffer))
- buffersize = sizeof(Buffer);
- else
- buffersize = _buffersize;
- initsize = initpoolsize * buffersize;
- nextsize = initsize;
- name = n;
- magic = is_allocated;
- nextblock = 0;
- curblock = 0;
- freelist = 0;
- nextfree = 0;
- for (int i = 0; i < NBLOCKS; i++) {
- blocklist[i] = 0;
- }
-}
-
-/*-----------------------------------------------------------------------------
- * ~Pool - free a pool of buffers and the pool itself
- *-----------------------------------------------------------------------------
- */
-
-Pool::~Pool( void )
-{
- assert( (this != 0) && (magic == is_allocated) );
-
- while( nextblock ) {
- delete [] blocklist[--nextblock];
- blocklist[nextblock] = 0;
- }
- magic = is_free;
-}
-
-
-void Pool::grow( void )
-{
- assert( (this != 0) && (magic == is_allocated) );
- curblock = new char[nextsize];
- blocklist[nextblock++] = curblock;
- nextfree = nextsize;
- nextsize *= 2;
-}
-
-/*-----------------------------------------------------------------------------
- * Pool::clear - free buffers associated with pool but keep pool
- *-----------------------------------------------------------------------------
- */
-
-void
-Pool::clear( void )
-{
- assert( (this != 0) && (magic == is_allocated) );
-
- while( nextblock ) {
- delete [] blocklist[--nextblock];
- blocklist[nextblock] = 0;
- }
- curblock = 0;
- freelist = 0;
- nextfree = 0;
- if( nextsize > initsize )
- nextsize /= 2;
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * bufpool.h
- *
- */
-
-#ifndef __glubufpool_h_
-#define __glubufpool_h_
-
-#include "gluos.h"
-#include "myassert.h"
-#include "mystdlib.h"
-
-#define NBLOCKS 32
-
-class Buffer {
- friend class Pool;
- Buffer * next; /* next buffer on free list */
-};
-
-class Pool {
-public:
- Pool( int, int, const char * );
- ~Pool( void );
- inline void* new_buffer( void );
- inline void free_buffer( void * );
- void clear( void );
-
-private:
- void grow( void );
-
-protected:
- Buffer *freelist; /* linked list of free buffers */
- char *blocklist[NBLOCKS]; /* blocks of malloced memory */
- int nextblock; /* next free block index */
- char *curblock; /* last malloced block */
- int buffersize; /* bytes per buffer */
- int nextsize; /* size of next block of memory */
- int nextfree; /* byte offset past next free buffer */
- int initsize;
- enum Magic { is_allocated = 0xf3a1, is_free = 0xf1a2 };
- const char *name; /* name of the pool */
- Magic magic; /* marker for valid pool */
-};
-
-/*-----------------------------------------------------------------------------
- * Pool::free_buffer - return a buffer to a pool
- *-----------------------------------------------------------------------------
- */
-
-inline void
-Pool::free_buffer( void *b )
-{
- assert( (this != 0) && (magic == is_allocated) );
-
- /* add buffer to singly connected free list */
-
- ((Buffer *) b)->next = freelist;
- freelist = (Buffer *) b;
-}
-
-
-/*-----------------------------------------------------------------------------
- * Pool::new_buffer - allocate a buffer from a pool
- *-----------------------------------------------------------------------------
- */
-
-inline void *
-Pool::new_buffer( void )
-{
- void *buffer;
-
- assert( (this != 0) && (magic == is_allocated) );
-
- /* find free buffer */
-
- if( freelist ) {
- buffer = (void *) freelist;
- freelist = freelist->next;
- } else {
- if( ! nextfree )
- grow( );
- nextfree -= buffersize;;
- buffer = (void *) (curblock + nextfree);
- }
- return buffer;
-}
-
-class PooledObj {
-public:
- inline void * operator new( size_t, Pool & );
- inline void * operator new( size_t, void *);
- inline void * operator new( size_t s)
- { return ::new char[s]; }
- inline void operator delete( void * ) { assert( 0 ); }
- inline void operator delete( void *, Pool & ) { assert( 0 ); }
- inline void deleteMe( Pool & );
-};
-
-inline void *
-PooledObj::operator new( size_t, Pool& pool )
-{
- return pool.new_buffer();
-}
-
-inline void
-PooledObj::deleteMe( Pool& pool )
-{
- pool.free_buffer( (void *) this );
-}
-
-#endif /* __glubufpool_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * cachingeval.c++
- *
- */
-
-#include "cachingeval.h"
-
-int
-CachingEvaluator::canRecord( void )
-{
- return 0;
-}
-
-int
-CachingEvaluator::canPlayAndRecord( void )
-{
- return 0;
-}
-
-int
-CachingEvaluator::createHandle( int )
-{
- return 0;
-}
-
-void
-CachingEvaluator::beginOutput( ServiceMode, int )
-{
-}
-
-void
-CachingEvaluator::endOutput( void )
-{
-}
-
-void
-CachingEvaluator::discardRecording( int )
-{
-}
-
-void
-CachingEvaluator::playRecording( int )
-{
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * cachingeval.h
- *
- */
-
-#ifndef __glucachingval_h_
-#define __glucachingval_h_
-
-class CachingEvaluator {
-public:
- virtual ~CachingEvaluator() { /* silence warning*/ }
- enum ServiceMode { play, record, playAndRecord };
- virtual int canRecord( void );
- virtual int canPlayAndRecord( void );
- virtual int createHandle( int handle );
- virtual void beginOutput( ServiceMode, int handle );
- virtual void endOutput( void );
- virtual void discardRecording( int handle );
- virtual void playRecording( int handle );
-};
-#endif /* __glucachingval_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * ccw.c++
- *
- */
-
-#include "glimports.h"
-#include "mystdio.h"
-#include "myassert.h"
-#include "subdivider.h"
-#include "types.h"
-#include "arc.h"
-#include "trimvertex.h"
-#include "simplemath.h"
-
-inline int
-Subdivider::bbox( TrimVertex *a, TrimVertex *b, TrimVertex *c, int p )
-{
- return bbox( a->param[p], b->param[p], c->param[p],
- a->param[1-p], b->param[1-p], c->param[1-p] );
-}
-
-int
-Subdivider::ccwTurn_sr( Arc_ptr j1, Arc_ptr j2 ) // dir = 1
-{
- register TrimVertex *v1 = &j1->pwlArc->pts[j1->pwlArc->npts-1];
- register TrimVertex *v1last = &j1->pwlArc->pts[0];
- register TrimVertex *v2 = &j2->pwlArc->pts[0];
- register TrimVertex *v2last = &j2->pwlArc->pts[j2->pwlArc->npts-1];
- register TrimVertex *v1next = v1-1;
- register TrimVertex *v2next = v2+1;
- int sgn;
-
- assert( v1 != v1last );
- assert( v2 != v2last );
-
-#ifndef NDEBUG
- _glu_dprintf( "arc_ccw_turn, p = %d\n", 0 );
-#endif
-
- // the arcs lie on the line (0 == v1->param[0])
- if( v1->param[0] == v1next->param[0] && v2->param[0] == v2next->param[0] )
- return 0;
-
- if( v2next->param[0] < v2->param[0] || v1next->param[0] < v1->param[0] )
- ::mylongjmp( jumpbuffer, 28 );
-
- if( v1->param[1] < v2->param[1] )
- return 0;
- else if( v1->param[1] > v2->param[1] )
- return 1;
-
- while( 1 ) {
- if( v1next->param[0] < v2next->param[0] ) {
-#ifndef NDEBUG
- _glu_dprintf( "case a\n" );
-#endif
- assert( v1->param[0] <= v1next->param[0] );
- assert( v2->param[0] <= v1next->param[0] );
- switch( bbox( v2, v2next, v1next, 1 ) ) {
- case -1:
- return 0;
- case 0:
- sgn = ccw( v1next, v2, v2next );
- if( sgn != -1 ) {
- return sgn;
- } else {
-#ifdef DEBUG
- _glu_dprintf( "decr\n" );
-#endif
- v1 = v1next--;
- if( v1 == v1last ) {
-#ifdef DEBUG
- _glu_dprintf( "no good results\n" );
-#endif
- return 0; // ill-conditioned, guess answer
- }
- }
- break;
- case 1:
- return 1;
- }
- } else if( v1next->param[0] > v2next->param[0] ) {
-#ifndef NDEBUG
- _glu_dprintf( "case b\n" );
-#endif
- assert( v1->param[0] <= v2next->param[0] );
- assert( v2->param[0] <= v2next->param[0] );
- switch( bbox( v1, v1next, v2next, 1 ) ) {
- case -1:
- return 1;
- case 0:
- sgn = ccw( v1next, v1, v2next );
- if( sgn != -1 ) {
- return sgn;
- } else {
-#ifdef DEBUG
- _glu_dprintf( "incr\n" );
-#endif
- v2 = v2next++;
- if( v2 == v2last ) {
-#ifdef DEBUG
- _glu_dprintf( "no good results\n" );
-#endif
- return 0; // ill-conditioned, guess answer
- }
- }
- break;
- case 1:
- return 0;
- }
- } else {
-#ifndef NDEBUG
- _glu_dprintf( "case ab\n" );
-#endif
- if( v1next->param[1] < v2next->param[1] )
- return 0;
- else if( v1next->param[1] > v2next->param[1] )
- return 1;
- else {
-#ifdef DEBUG
- _glu_dprintf( "incr\n" );
-#endif
- v2 = v2next++;
- if( v2 == v2last ) {
-#ifdef DEBUG
- _glu_dprintf( "no good results\n" );
-#endif
- return 0; // ill-conditioned, guess answer
- }
- }
- }
- }
-}
-
-int
-Subdivider::ccwTurn_sl( Arc_ptr j1, Arc_ptr j2 ) // dir = 0
-{
- register TrimVertex *v1 = &j1->pwlArc->pts[j1->pwlArc->npts-1];
- register TrimVertex *v1last = &j1->pwlArc->pts[0];
- register TrimVertex *v2 = &j2->pwlArc->pts[0];
- register TrimVertex *v2last = &j2->pwlArc->pts[j2->pwlArc->npts-1];
- register TrimVertex *v1next = v1-1;
- register TrimVertex *v2next = v2+1;
- int sgn;
-
- assert( v1 != v1last );
- assert( v2 != v2last );
-
-#ifndef NDEBUG
- _glu_dprintf( "arc_ccw_turn, p = %d\n", 0 );
-#endif
-
- // the arcs lie on the line (0 == v1->param[0])
- if( v1->param[0] == v1next->param[0] && v2->param[0] == v2next->param[0] )
- return 0;
-
- if( v2next->param[0] > v2->param[0] || v1next->param[0] > v1->param[0] )
- ::mylongjmp( jumpbuffer, 28 );
-
- if( v1->param[1] < v2->param[1] )
- return 1;
- else if( v1->param[1] > v2->param[1] )
- return 0;
-
- while( 1 ) {
- if( v1next->param[0] > v2next->param[0] ) {
-#ifndef NDEBUG
- _glu_dprintf( "case c\n" );
-#endif
- assert( v1->param[0] >= v1next->param[0] );
- assert( v2->param[0] >= v1next->param[0] );
- switch( bbox( v2next, v2, v1next, 1 ) ) {
- case -1:
- return 1;
- case 0:
- sgn = ccw( v1next, v2, v2next );
- if( sgn != -1 )
- return sgn;
- else {
- v1 = v1next--;
-#ifdef DEBUG
- _glu_dprintf( "decr\n" );
-#endif
- if( v1 == v1last ) {
-#ifdef DEBUG
- _glu_dprintf( "no good results\n" );
-#endif
- return 0; // ill-conditioned, guess answer
- }
- }
- break;
- case 1:
- return 0;
- }
- } else if( v1next->param[0] < v2next->param[0] ) {
-#ifndef NDEBUG
- _glu_dprintf( "case d\n" );
-#endif
- assert( v1->param[0] >= v2next->param[0] );
- assert( v2->param[0] >= v2next->param[0] );
- switch( bbox( v1next, v1, v2next, 1 ) ) {
- case -1:
- return 0;
- case 0:
- sgn = ccw( v1next, v1, v2next );
- if( sgn != -1 )
- return sgn;
- else {
- v2 = v2next++;
-#ifdef DEBUG
- _glu_dprintf( "incr\n" );
-#endif
- if( v2 == v2last ) {
-#ifdef DEBUG
- _glu_dprintf( "no good results\n" );
-#endif
- return 0; // ill-conditioned, guess answer
- }
- }
- break;
- case 1:
- return 1;
- }
- } else {
-#ifdef DEBUG
- _glu_dprintf( "case cd\n" );
-#endif
- if( v1next->param[1] < v2next->param[1] )
- return 1;
- else if( v1next->param[1] > v2next->param[1] )
- return 0;
- else {
- v2 = v2next++;
-#ifdef DEBUG
- _glu_dprintf( "incr\n" );
-#endif
- if( v2 == v2last ) {
-#ifdef DEBUG
- _glu_dprintf( "no good results\n" );
-#endif
- return 0; // ill-conditioned, guess answer
- }
- }
- }
- }
-}
-
-int
-Subdivider::ccwTurn_tr( Arc_ptr j1, Arc_ptr j2 ) // dir = 1
-{
- register TrimVertex *v1 = &j1->pwlArc->pts[j1->pwlArc->npts-1];
- register TrimVertex *v1last = &j1->pwlArc->pts[0];
- register TrimVertex *v2 = &j2->pwlArc->pts[0];
- register TrimVertex *v2last = &j2->pwlArc->pts[j2->pwlArc->npts-1];
- register TrimVertex *v1next = v1-1;
- register TrimVertex *v2next = v2+1;
- int sgn;
-
- assert( v1 != v1last );
- assert( v2 != v2last );
-
-#ifndef NDEBUG
- _glu_dprintf( "arc_ccw_turn, p = %d\n", 1 );
-#endif
-
- // the arcs lie on the line (1 == v1->param[1])
- if( v1->param[1] == v1next->param[1] && v2->param[1] == v2next->param[1] )
- return 0;
-
- if( v2next->param[1] < v2->param[1] || v1next->param[1] < v1->param[1] )
- ::mylongjmp( jumpbuffer, 28 );
-
- if( v1->param[0] < v2->param[0] )
- return 1;
- else if( v1->param[0] > v2->param[0] )
- return 0;
-
- while( 1 ) {
- if( v1next->param[1] < v2next->param[1] ) {
-#ifndef NDEBUG
- _glu_dprintf( "case a\n" );
-#endif
- assert( v1->param[1] <= v1next->param[1] );
- assert( v2->param[1] <= v1next->param[1] );
- switch( bbox( v2, v2next, v1next, 0 ) ) {
- case -1:
- return 1;
- case 0:
- sgn = ccw( v1next, v2, v2next );
- if( sgn != -1 ) {
- return sgn;
- } else {
-#ifdef DEBUG
- _glu_dprintf( "decr\n" );
-#endif
- v1 = v1next--;
- if( v1 == v1last ) {
-#ifdef DEBUG
- _glu_dprintf( "no good results\n" );
-#endif
- return 0; // ill-conditioned, guess answer
- }
- }
- break;
- case 1:
- return 0;
- }
- } else if( v1next->param[1] > v2next->param[1] ) {
-#ifndef NDEBUG
- _glu_dprintf( "case b\n" );
-#endif
- assert( v1->param[1] <= v2next->param[1] );
- assert( v2->param[1] <= v2next->param[1] );
- switch( bbox( v1, v1next, v2next, 0 ) ) {
- case -1:
- return 0;
- case 0:
- sgn = ccw( v1next, v1, v2next );
- if( sgn != -1 ) {
- return sgn;
- } else {
-#ifdef DEBUG
- _glu_dprintf( "incr\n" );
-#endif
- v2 = v2next++;
- if( v2 == v2last ) {
-#ifdef DEBUG
- _glu_dprintf( "no good results\n" );
-#endif
- return 0; // ill-conditioned, guess answer
- }
- }
- break;
- case 1:
- return 1;
- }
- } else {
-#ifdef DEBUG
- _glu_dprintf( "case ab\n" );
-#endif
- if( v1next->param[0] < v2next->param[0] )
- return 1;
- else if( v1next->param[0] > v2next->param[0] )
- return 0;
- else {
-#ifdef DEBUG
- _glu_dprintf( "incr\n" );
-#endif
- v2 = v2next++;
- if( v2 == v2last ) {
-#ifdef DEBUG
- _glu_dprintf( "no good results\n" );
-#endif
- return 0; // ill-conditioned, guess answer
- }
- }
- }
- }
-}
-
-int
-Subdivider::ccwTurn_tl( Arc_ptr j1, Arc_ptr j2 )
-{
- register TrimVertex *v1 = &j1->pwlArc->pts[j1->pwlArc->npts-1];
- register TrimVertex *v1last = &j1->pwlArc->pts[0];
- register TrimVertex *v2 = &j2->pwlArc->pts[0];
- register TrimVertex *v2last = &j2->pwlArc->pts[j2->pwlArc->npts-1];
- register TrimVertex *v1next = v1-1;
- register TrimVertex *v2next = v2+1;
- int sgn;
-
- assert( v1 != v1last );
- assert( v2 != v2last );
-
-#ifndef NDEBUG
- _glu_dprintf( "arc_ccw_turn, p = %d\n", 1 );
-#endif
-
- // the arcs lie on the line (1 == v1->param[1])
- if( v1->param[1] == v1next->param[1] && v2->param[1] == v2next->param[1] )
- return 0;
-
- if( v2next->param[1] > v2->param[1] || v1next->param[1] > v1->param[1] )
- ::mylongjmp( jumpbuffer, 28 );
-
- if( v1->param[0] < v2->param[0] )
- return 0;
- else if( v1->param[0] > v2->param[0] )
- return 1;
-
- while( 1 ) {
- if( v1next->param[1] > v2next->param[1] ) {
-#ifndef NDEBUG
- _glu_dprintf( "case c\n" );
-#endif
- assert( v1->param[1] >= v1next->param[1] );
- assert( v2->param[1] >= v1next->param[1] );
- switch( bbox( v2next, v2, v1next, 0 ) ) {
- case -1:
- return 0;
- case 0:
- sgn = ccw( v1next, v2, v2next );
- if( sgn != -1 )
- return sgn;
- else {
- v1 = v1next--;
-#ifdef DEBUG
- _glu_dprintf( "decr\n" );
-#endif
- if( v1 == v1last ) {
-#ifdef DEBUG
- _glu_dprintf( "no good results\n" );
-#endif
- return 0; // ill-conditioned, guess answer
- }
- }
- break;
- case 1:
- return 1;
- }
- } else if( v1next->param[1] < v2next->param[1] ) {
-#ifndef NDEBUG
- _glu_dprintf( "case d\n" );
- assert( v1->param[1] >= v2next->param[1] );
- assert( v2->param[1] >= v2next->param[1] );
-#endif
- switch( bbox( v1next, v1, v2next, 0 ) ) {
- case -1:
- return 1;
- case 0:
- sgn = ccw( v1next, v1, v2next );
- if( sgn != -1 )
- return sgn;
- else {
- v2 = v2next++;
-#ifdef DEBUG
- _glu_dprintf( "incr\n" );
-#endif
- if( v2 == v2last ) {
-#ifdef DEBUG
- _glu_dprintf( "no good results\n" );
-#endif
- return 0; // ill-conditioned, guess answer
- }
- }
- break;
- case 1:
- return 0;
- }
- } else {
-#ifdef DEBUG
- _glu_dprintf( "case cd\n" );
-#endif
- if( v1next->param[0] < v2next->param[0] )
- return 0;
- else if( v1next->param[0] > v2next->param[0] )
- return 1;
- else {
- v2 = v2next++;
-#ifdef DEBUG
- _glu_dprintf( "incr\n" );
-#endif
- if( v2 == v2last ) {
-#ifdef DEBUG
- _glu_dprintf( "no good results\n" );
-#endif
- return 0; // ill-conditioned, guess answer
- }
- }
- }
- }
-}
-
-
-#ifndef NDEBUG
-int
-Subdivider::bbox( register REAL sa, register REAL sb, register REAL sc,
- register REAL ta, register REAL tb, register REAL tc )
-#else
-int
-Subdivider::bbox( register REAL sa, register REAL sb, register REAL sc,
- register REAL , register REAL , register REAL )
-#endif
-{
-#ifndef NDEBUG
- assert( tc >= ta );
- assert( tc <= tb );
-#endif
-
- if( sa < sb ) {
- if( sc <= sa ) {
- return -1;
- } else if( sb <= sc ) {
- return 1;
- } else {
- return 0;
- }
- } else if( sa > sb ) {
- if( sc >= sa ) {
- return 1;
- } else if( sb >= sc ) {
- return -1;
- } else {
- return 0;
- }
- } else {
- if( sc > sa ) {
- return 1;
- } else if( sb > sc ) {
- return -1;
- } else {
- return 0;
- }
- }
-}
-
-/*----------------------------------------------------------------------------
- * ccw - determine how three points are oriented by computing their
- * determinant.
- * Return 1 if the vertices are ccw oriented,
- * 0 if they are cw oriented, or
- * -1 if the computation is ill-conditioned.
- *----------------------------------------------------------------------------
- */
-int
-Subdivider::ccw( TrimVertex *a, TrimVertex *b, TrimVertex *c )
-{
- REAL d = det3( a, b, c );
- if( glu_abs(d) < 0.0001 ) return -1;
- return (d < 0.0) ? 0 : 1;
-}
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * coveandtiler.c++
- *
- */
-
-#include "glimports.h"
-#include "myassert.h"
-#include "mystdio.h"
-#include "coveandtiler.h"
-#include "gridvertex.h"
-#include "gridtrimvertex.h"
-#include "uarray.h"
-#include "backend.h"
-
-
-const int CoveAndTiler::MAXSTRIPSIZE = 1000;
-
-CoveAndTiler::CoveAndTiler( Backend& b )
- : backend( b )
-{ }
-
-CoveAndTiler::~CoveAndTiler( void )
-{ }
-
-inline void
-CoveAndTiler::output( GridVertex &gv )
-{
- backend.tmeshvert( &gv );
-}
-
-inline void
-CoveAndTiler::output( TrimVertex *tv )
-{
- backend.tmeshvert( tv );
-}
-
-inline void
-CoveAndTiler::output( GridTrimVertex& g )
-{
- backend.tmeshvert( &g );
-}
-
-void
-CoveAndTiler::coveAndTile( void )
-{
- long ustart = (top.ustart >= bot.ustart) ? top.ustart : bot.ustart;
- long uend = (top.uend <= bot.uend) ? top.uend : bot.uend;
- if( ustart <= uend ) {
- tile( bot.vindex, ustart, uend );
- if( top.ustart >= bot.ustart )
- coveUpperLeft();
- else
- coveLowerLeft();
-
- if( top.uend <= bot.uend )
- coveUpperRight();
- else
- coveLowerRight();
- } else {
- TrimVertex blv, tlv, *bl, *tl;
- GridTrimVertex bllv, tllv;
- TrimVertex *lf = left.first();
- TrimVertex *ll = left.last();
- if( lf->param[0] >= ll->param[0] ) {
- blv.param[0] = lf->param[0];
- blv.param[1] = ll->param[1];
- blv.nuid = 0; // XXX
- assert( blv.param[1] == bot.vval );
- bl = &blv;
- tl = lf;
- tllv.set( lf );
- if( ll->param[0] > uarray.uarray[top.ustart-1] ) {
- bllv.set( ll );
- assert( ll->param[0] <= uarray.uarray[bot.ustart] );
- } else {
- bllv.set( top.ustart-1, bot.vindex );
- }
- coveUpperLeftNoGrid( bl );
- } else {
- tlv.param[0] = ll->param[0];
- tlv.param[1] = lf->param[1];
- tlv.nuid = 0; // XXX
- assert( tlv.param[1] == top.vval );
- tl = &tlv;
- bl = ll;
- bllv.set( ll );
- if( lf->param[0] > uarray.uarray[bot.ustart-1] ) {
- assert( lf->param[0] <= uarray.uarray[bot.ustart] );
- tllv.set( lf );
- } else {
- tllv.set( bot.ustart-1, top.vindex );
- }
- coveLowerLeftNoGrid( tl );
- }
-
- TrimVertex brv, trv, *br, *tr;
- GridTrimVertex brrv, trrv;
- TrimVertex *rf = right.first();
- TrimVertex *rl = right.last();
-
- if( rf->param[0] <= rl->param[0] ) {
- brv.param[0] = rf->param[0];
- brv.param[1] = rl->param[1];
- brv.nuid = 0; // XXX
- assert( brv.param[1] == bot.vval );
- br = &brv;
- tr = rf;
- trrv.set( rf );
- if( rl->param[0] < uarray.uarray[top.uend+1] ) {
- assert( rl->param[0] >= uarray.uarray[top.uend] );
- brrv.set( rl );
- } else {
- brrv.set( top.uend+1, bot.vindex );
- }
- coveUpperRightNoGrid( br );
- } else {
- trv.param[0] = rl->param[0];
- trv.param[1] = rf->param[1];
- trv.nuid = 0; // XXX
- assert( trv.param[1] == top.vval );
- tr = &trv;
- br = rl;
- brrv.set( rl );
- if( rf->param[0] < uarray.uarray[bot.uend+1] ) {
- assert( rf->param[0] >= uarray.uarray[bot.uend] );
- trrv.set( rf );
- } else {
- trrv.set( bot.uend+1, top.vindex );
- }
- coveLowerRightNoGrid( tr );
- }
-
- backend.bgntmesh( "doit" );
- output(trrv);
- output(tllv);
- output( tr );
- output( tl );
- output( br );
- output( bl );
- output(brrv);
- output(bllv);
- backend.endtmesh();
- }
-}
-
-void
-CoveAndTiler::tile( long vindex, long ustart, long uend )
-{
- long numsteps = uend - ustart;
-
- if( numsteps == 0 ) return;
-
- if( numsteps > MAXSTRIPSIZE ) {
- long umid = ustart + (uend - ustart) / 2;
- tile( vindex, ustart, umid );
- tile( vindex, umid, uend );
- } else {
- backend.surfmesh( ustart, vindex-1, numsteps, 1 );
- }
-}
-
-void
-CoveAndTiler::coveUpperRight( void )
-{
- GridVertex tgv( top.uend, top.vindex );
- GridVertex gv( top.uend, bot.vindex );
-
- right.first();
- backend.bgntmesh( "coveUpperRight" );
- output( right.next() );
- output( tgv );
- backend.swaptmesh();
- output( gv );
- coveUR();
- backend.endtmesh();
-}
-
-void
-CoveAndTiler::coveUpperRightNoGrid( TrimVertex* br )
-{
- backend.bgntmesh( "coveUpperRight" );
- output( right.first() );
- output( right.next() );
- backend.swaptmesh();
- output( br );
- coveUR();
- backend.endtmesh();
-}
-
-void
-CoveAndTiler::coveUR( )
-{
- GridVertex gv( top.uend, bot.vindex );
- TrimVertex *vert = right.next();
- if( vert == NULL ) return;
-
- assert( vert->param[0] >= uarray.uarray[gv.gparam[0]] );
-
- if( gv.nextu() >= bot.uend ) {
- for( ; vert; vert = right.next() ) {
- output( vert );
- backend.swaptmesh();
- }
- } else while( 1 ) {
- if( vert->param[0] < uarray.uarray[gv.gparam[0]] ) {
- output( vert );
- backend.swaptmesh();
- vert = right.next();
- if( vert == NULL ) break;
- } else {
- backend.swaptmesh();
- output( gv );
- if( gv.nextu() == bot.uend ) {
- for( ; vert; vert = right.next() ) {
- output( vert );
- backend.swaptmesh();
- }
- break;
- }
- }
- }
-}
-
-void
-CoveAndTiler::coveUpperLeft( void )
-{
- GridVertex tgv( top.ustart, top.vindex );
- GridVertex gv( top.ustart, bot.vindex );
-
- left.first();
- backend.bgntmesh( "coveUpperLeft" );
- output( tgv );
- output( left.next() );
- output( gv );
- backend.swaptmesh();
- coveUL();
- backend.endtmesh();
-}
-
-void
-CoveAndTiler::coveUpperLeftNoGrid( TrimVertex* bl )
-{
- backend.bgntmesh( "coveUpperLeftNoGrid" );
- output( left.first() );
- output( left.next() );
- output( bl );
- backend.swaptmesh();
- coveUL();
- backend.endtmesh();
-}
-
-void
-CoveAndTiler::coveUL()
-{
- GridVertex gv( top.ustart, bot.vindex );
- TrimVertex *vert = left.next();
- if( vert == NULL ) return;
- assert( vert->param[0] <= uarray.uarray[gv.gparam[0]] );
-
- if( gv.prevu() <= bot.ustart ) {
- for( ; vert; vert = left.next() ) {
- backend.swaptmesh();
- output( vert );
- }
- } else while( 1 ) {
- if( vert->param[0] > uarray.uarray[gv.gparam[0]] ) {
- backend.swaptmesh();
- output( vert );
- vert = left.next();
- if( vert == NULL ) break;
- } else {
- output( gv );
- backend.swaptmesh();
- if( gv.prevu() == bot.ustart ) {
- for( ; vert; vert = left.next() ) {
- backend.swaptmesh();
- output( vert );
- }
- break;
- }
- }
- }
-}
-
-void
-CoveAndTiler::coveLowerLeft( void )
-{
- GridVertex bgv( bot.ustart, bot.vindex );
- GridVertex gv( bot.ustart, top.vindex );
-
- left.last();
- backend.bgntmesh( "coveLowerLeft" );
- output( left.prev() );
- output( bgv );
- backend.swaptmesh();
- output( gv );
- coveLL();
- backend.endtmesh();
-}
-
-void
-CoveAndTiler::coveLowerLeftNoGrid( TrimVertex* tl )
-{
- backend.bgntmesh( "coveLowerLeft" );
- output( left.last() );
- output( left.prev() );
- backend.swaptmesh();
- output( tl );
- coveLL( );
- backend.endtmesh();
-}
-
-void
-CoveAndTiler::coveLL()
-{
- GridVertex gv( bot.ustart, top.vindex );
- TrimVertex *vert = left.prev();
- if( vert == NULL ) return;
- assert( vert->param[0] <= uarray.uarray[gv.gparam[0]] );
-
- if( gv.prevu() <= top.ustart ) {
- for( ; vert; vert = left.prev() ) {
- output( vert );
- backend.swaptmesh();
- }
- } else while( 1 ) {
- if( vert->param[0] > uarray.uarray[gv.gparam[0]] ){
- output( vert );
- backend.swaptmesh();
- vert = left.prev();
- if( vert == NULL ) break;
- } else {
- backend.swaptmesh();
- output( gv );
- if( gv.prevu() == top.ustart ) {
- for( ; vert; vert = left.prev() ) {
- output( vert );
- backend.swaptmesh();
- }
- break;
- }
- }
- }
-}
-
-void
-CoveAndTiler::coveLowerRight( void )
-{
- GridVertex bgv( bot.uend, bot.vindex );
- GridVertex gv( bot.uend, top.vindex );
-
- right.last();
- backend.bgntmesh( "coveLowerRight" );
- output( bgv );
- output( right.prev() );
- output( gv );
- backend.swaptmesh();
- coveLR();
- backend.endtmesh( );
-}
-
-void
-CoveAndTiler::coveLowerRightNoGrid( TrimVertex* tr )
-{
- backend.bgntmesh( "coveLowerRIght" );
- output( right.last() );
- output( right.prev() );
- output( tr );
- backend.swaptmesh();
- coveLR();
- backend.endtmesh();
-}
-
-void
-CoveAndTiler::coveLR( )
-{
- GridVertex gv( bot.uend, top.vindex );
- TrimVertex *vert = right.prev();
- if( vert == NULL ) return;
- assert( vert->param[0] >= uarray.uarray[gv.gparam[0]] );
-
- if( gv.nextu() >= top.uend ) {
- for( ; vert; vert = right.prev() ) {
- backend.swaptmesh();
- output( vert );
- }
- } else while( 1 ) {
- if( vert->param[0] < uarray.uarray[gv.gparam[0]] ) {
- backend.swaptmesh();
- output( vert );
- vert = right.prev();
- if( vert == NULL ) break;
- } else {
- output( gv );
- backend.swaptmesh();
- if( gv.nextu() == top.uend ) {
- for( ; vert; vert = right.prev() ) {
- backend.swaptmesh();
- output( vert );
- }
- break;
- }
- }
- }
-}
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * coveandtiler.h
- *
- */
-
-#ifndef __glucoveandtiler_h
-#define __glucoveandtiler_h
-
-#include "trimregion.h"
-#include "trimvertex.h"
-#include "gridvertex.h"
-
-class Backend;
-class GridTrimVertex;
-
-class CoveAndTiler : virtual public TrimRegion {
-public:
- CoveAndTiler( Backend& );
- ~CoveAndTiler( void );
- void coveAndTile( void );
-private:
- Backend& backend;
- static const int MAXSTRIPSIZE;
- void tile( long, long, long );
- void coveLowerLeft( void );
- void coveLowerRight( void );
- void coveUpperLeft( void );
- void coveUpperRight( void );
- void coveUpperLeftNoGrid( TrimVertex * );
- void coveUpperRightNoGrid( TrimVertex * );
- void coveLowerLeftNoGrid( TrimVertex * );
- void coveLowerRightNoGrid( TrimVertex * );
- void coveLL( void );
- void coveLR( void );
- void coveUL( void );
- void coveUR( void );
- inline void output( GridTrimVertex& );
- inline void output( GridVertex& );
- inline void output( TrimVertex* );
-};
-
-#endif /* __glucoveandtiler_h */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * curve.c++
- *
- */
-
-#include "glimports.h"
-#include "myassert.h"
-#include "mystdio.h"
-#include "mymath.h"
-#include "curve.h"
-#include "mapdesc.h"
-#include "types.h"
-#include "quilt.h"
-#include "nurbsconsts.h"
-
-/*--------------------------------------------------------------------------
- * Curve::Curve - copy curve from quilt and transform control points
- *--------------------------------------------------------------------------
- */
-
-Curve::Curve( Quilt_ptr geo, REAL pta, REAL ptb, Curve *c )
-{
- mapdesc = geo->mapdesc;
- next = c;
- needsSampling = mapdesc->isRangeSampling() ? 1 : 0;
- cullval = mapdesc->isCulling() ? CULL_ACCEPT : CULL_TRIVIAL_ACCEPT;
- order = geo->qspec[0].order;
- stride = MAXCOORDS;
- for( int i = 0; i < MAXORDER * MAXCOORDS; i++ ) {
- cpts[i] = 0;
- spts[i] = 0;
- }
- stepsize = 0;
- minstepsize = 0;
-
- REAL *ps = geo->cpts;
- Quiltspec_ptr qs = geo->qspec;
- ps += qs->offset;
- ps += qs->index * qs->order * qs->stride;
-
- if( needsSampling )
- mapdesc->xformSampling( ps, qs->order, qs->stride, spts, stride );
-
- if( cullval == CULL_ACCEPT )
- mapdesc->xformCulling( ps, qs->order, qs->stride, cpts, stride );
-
- /* set untrimmed curve range */
- range[0] = qs->breakpoints[qs->index];
- range[1] = qs->breakpoints[qs->index+1];
- range[2] = range[1] - range[0];
-
- if( range[0] != pta ) {
- Curve lower( *this, pta, 0 );
- lower.next = next;
- *this = lower;
- }
- if( range[1] != ptb ) {
- Curve lower( *this, ptb, 0 );
- }
-}
-
-/*--------------------------------------------------------------------------
- * Curve::Curve - subdivide a curve along an isoparametric line
- *--------------------------------------------------------------------------
- */
-
-Curve::Curve( Curve& upper, REAL value, Curve *c )
-{
- Curve &lower = *this;
-
- lower.next = c;
- lower.mapdesc = upper.mapdesc;
- lower.needsSampling = upper.needsSampling;
- lower.order = upper.order;
- lower.stride = upper.stride;
- lower.cullval = upper.cullval;
-
- REAL d = (value - upper.range[0]) / upper.range[2];
-
- if( needsSampling )
- mapdesc->subdivide( upper.spts, lower.spts, d, upper.stride, upper.order );
-
- if( cullval == CULL_ACCEPT )
- mapdesc->subdivide( upper.cpts, lower.cpts, d, upper.stride, upper.order );
-
- lower.range[0] = upper.range[0];
- lower.range[1] = value;
- lower.range[2] = value - upper.range[0];
- upper.range[0] = value;
- upper.range[2] = upper.range[1] - value;
-}
-
-
-/*--------------------------------------------------------------------------
- * Curve::clamp - clamp the sampling rate to a given maximum
- *--------------------------------------------------------------------------
- */
-
-void
-Curve::clamp( void )
-{
- if( stepsize < minstepsize )
- stepsize = mapdesc->clampfactor * minstepsize;
-}
-
-void
-Curve::setstepsize( REAL max )
-{
- stepsize = ( max >= 1.0 ) ? (range[2] / max) : range[2];
- minstepsize = stepsize;
-}
-
-void
-Curve::getstepsize( void )
-{
- minstepsize= 0;
-
- if( mapdesc->isConstantSampling() ) {
- // fixed number of samples per patch in each direction
- // maxrate is number of s samples per patch
- setstepsize( mapdesc->maxrate );
- } else if( mapdesc->isDomainSampling() ) {
- // maxrate is number of s samples per unit s length of domain
- setstepsize( mapdesc->maxrate * range[2] );
- } else {
- // upper bound on path length between sample points
-
- assert( order <= MAXORDER );
-
- /* points have been transformed, therefore they are homogeneous */
- REAL tmp[MAXORDER][MAXCOORDS];
- const int tstride = sizeof(tmp[0]) / sizeof(REAL);
- int val = mapdesc->project( spts, stride, &tmp[0][0], tstride, order );
-
- if( val == 0 ) {
- // control points cross infinity, therefore derivatives are undefined
- setstepsize( mapdesc->maxrate );
- } else {
- REAL t = mapdesc->getProperty( N_PIXEL_TOLERANCE );
- if( mapdesc->isParametricDistanceSampling() ) {
- REAL d = mapdesc->calcPartialVelocity( &tmp[0][0], tstride, order, 2, range[2] );
- stepsize = (d > 0.0) ? sqrtf( 8.0 * t / d ) : range[2];
- minstepsize = ( mapdesc->maxrate > 0.0 ) ? (range[2] / mapdesc->maxrate) : 0.0;
- } else if( mapdesc->isPathLengthSampling() ) {
- // t is upper bound on path (arc) length
- REAL d = mapdesc->calcPartialVelocity( &tmp[0][0], tstride, order, 1, range[2] );
- stepsize = ( d > 0.0 ) ? (t / d) : range[2];
- minstepsize = ( mapdesc->maxrate > 0.0 ) ? (range[2] / mapdesc->maxrate) : 0.0;
- } else {
- // control points cross infinity, therefore partials are undefined
- setstepsize( mapdesc->maxrate );
- }
- }
- }
-}
-
-int
-Curve::needsSamplingSubdivision( void )
-{
- return ( stepsize < minstepsize ) ? 1 : 0;
-}
-
-int
-Curve::cullCheck( void )
-{
- if( cullval == CULL_ACCEPT )
- cullval = mapdesc->cullCheck( cpts, order, stride );
- return cullval;
-}
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * curve.h
- *
- */
-
-#ifndef __glucurve_h_
-#define __glucurve_h_
-
-#include "types.h"
-#include "defines.h"
-
-class Mapdesc;
-class Quilt;
-
-
-class Curve {
-public:
-friend class Curvelist;
- Curve( Quilt *, REAL, REAL, Curve * );
- Curve( Curve&, REAL, Curve * );
- Curve * next;
-private:
- Mapdesc * mapdesc;
- int stride;
- int order;
- int cullval;
- int needsSampling;
- REAL cpts[MAXORDER*MAXCOORDS];
- REAL spts[MAXORDER*MAXCOORDS];
- REAL stepsize;
- REAL minstepsize;
- REAL range[3];
-
- void clamp( void );
- void setstepsize( REAL );
- void getstepsize( void );
- int cullCheck( void );
- int needsSamplingSubdivision( void );
-};
-#endif /* __glucurve_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * curvelist.c++
- *
- */
-
-#include "glimports.h"
-#include "myassert.h"
-#include "mystdio.h"
-#include "quilt.h"
-#include "curvelist.h"
-#include "curve.h"
-#include "types.h"
-
-Curvelist::Curvelist( Quilt *quilts, REAL pta, REAL ptb )
-{
- curve = 0;
- for( Quilt *q = quilts; q; q = q->next )
- curve = new Curve( q, pta, ptb, curve );
- range[0] = pta;
- range[1] = ptb;
- range[2] = ptb - pta;
- needsSubdivision = 0;
- stepsize = 0;
-}
-
-Curvelist::Curvelist( Curvelist &upper, REAL value )
-{
- curve = 0;
- for( Curve *c = upper.curve; c; c = c->next )
- curve = new Curve( *c, value, curve );
-
- range[0] = upper.range[0];
- range[1] = value;
- range[2] = value - upper.range[0];
- upper.range[0] = value;
- upper.range[2] = upper.range[1] - value;
- needsSubdivision = 0;
- stepsize = 0;
-}
-
-Curvelist::~Curvelist()
-{
- while( curve ) {
- Curve *c = curve;
- curve = curve->next;
- delete c;
- }
-}
-
-int
-Curvelist::cullCheck( void )
-{
- for( Curve *c = curve; c; c = c->next )
- if( c->cullCheck() == CULL_TRIVIAL_REJECT )
- return CULL_TRIVIAL_REJECT;
- return CULL_ACCEPT;
-}
-
-void
-Curvelist::getstepsize( void )
-{
- stepsize = range[2];
- Curve *c;
- for( c = curve; c; c = c->next ) {
- c->getstepsize();
- c->clamp();
- stepsize = ((c->stepsize < stepsize) ? c->stepsize : stepsize);
- if( c->needsSamplingSubdivision() ) break;
- }
- needsSubdivision = ( c ) ? 1 : 0;
-}
-
-int
-Curvelist::needsSamplingSubdivision( void )
-{
- return needsSubdivision;
-}
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * curvelist.h
- *
- */
-
-#ifndef __glucurvelist_h_
-#define __glucurvelist_h_
-
-#include "types.h"
-#include "defines.h"
-
-class Mapdesc;
-class Quilt;
-class Curve;
-
-class Curvelist
-{
-friend class Subdivider;
-public:
- Curvelist( Quilt *, REAL, REAL );
- Curvelist( Curvelist &, REAL );
- ~Curvelist( void );
- int cullCheck( void );
- void getstepsize( void );
- int needsSamplingSubdivision();
-private:
- Curve *curve;
- float range[3];
- int needsSubdivision;
- float stepsize;
-};
-#endif /* __glucurvelist_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * curvesub.c++
- *
- */
-
-#include "glimports.h"
-#include "myassert.h"
-#include "mystdio.h"
-#include "subdivider.h"
-#include "renderhints.h"
-#include "backend.h"
-#include "quilt.h"
-#include "curvelist.h"
-#include "nurbsconsts.h"
-
-/*--------------------------------------------------------------------------
- * drawCurves - main curve rendering entry point
- *--------------------------------------------------------------------------
- */
-
-void
-Subdivider::drawCurves( void )
-{
- REAL from[1], to[1];
- Flist bpts;
- qlist->getRange( from, to, bpts );
-
- renderhints.init( );
-
- backend.bgncurv();
- for( int i=bpts.start; i<bpts.end-1; i++ ) {
- REAL pta, ptb;
- pta = bpts.pts[i];
- ptb = bpts.pts[i+1];
-
- qlist->downloadAll( &pta, &ptb, backend );
-
- Curvelist curvelist( qlist, pta, ptb );
- samplingSplit( curvelist, renderhints.maxsubdivisions );
- }
- backend.endcurv();
-}
-
-
-/*--------------------------------------------------------------------------
- * samplingSplit - recursively subdivide patch, cull check each subpatch
- *--------------------------------------------------------------------------
- */
-
-void
-Subdivider::samplingSplit( Curvelist& curvelist, int subdivisions )
-{
- if( curvelist.cullCheck() == CULL_TRIVIAL_REJECT ) return;
-
- curvelist.getstepsize();
-
- if( curvelist.needsSamplingSubdivision() && (subdivisions > 0) ) {
- REAL mid = ( curvelist.range[0] + curvelist.range[1] ) * 0.5;
- Curvelist lowerlist( curvelist, mid );
- samplingSplit( lowerlist, subdivisions-1 ); // lower
- samplingSplit( curvelist, subdivisions-1 ); // upper
- } else {
- long nu = 1 + ((long) (curvelist.range[2] / curvelist.stepsize));
- backend.curvgrid( curvelist.range[0], curvelist.range[1], nu );
- backend.curvmesh( 0, nu );
- }
-}
-
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "glimports.h"
-#include "myassert.h"
-#include "nurbsconsts.h"
-#include "trimvertex.h"
-#include "dataTransform.h"
-
-extern directedLine* arcLoopToDLineLoop(Arc_ptr loop);
-
-#if 0 // UNUSED
-static directedLine* copy_loop(Arc_ptr loop, Real2* vertArray, int& index, directedLine dline_buf[], sampledLine sline_buf[], int& index_dline)
-{
- directedLine *ret;
- int old_index = index;
- int i = index;
- int j;
- for(j=0; j<loop->pwlArc->npts-1; j++, i++)
- {
- vertArray[i][0] = loop->pwlArc->pts[j].param[0];
- vertArray[i][1] = loop->pwlArc->pts[j].param[1];
- }
- loop->clearmark();
-
- for(Arc_ptr jarc = loop->next; jarc != loop; jarc=jarc->next)
- {
- for(j=0; j<jarc->pwlArc->npts-1; j++, i++)
- {
- vertArray[i][0] = jarc->pwlArc->pts[j].param[0];
- vertArray[i][1] = jarc->pwlArc->pts[j].param[1];
- }
- jarc->clearmark();
- }
- //copy the first vertex again
- vertArray[i][0] = loop->pwlArc->pts[0].param[0];
- vertArray[i][1] = loop->pwlArc->pts[0].param[1];
- i++;
- index=i;
-
- directedLine* dline;
- sampledLine* sline;
- sline = &sline_buf[index_dline];
- dline = &dline_buf[index_dline];
- sline->init(2, &vertArray[old_index]);
- dline->init(INCREASING, sline);
- ret = dline;
- index_dline++;
-
- for(i=old_index+1; i<= index-2; i++)
- {
- sline = &sline_buf[index_dline];
- dline = &dline_buf[index_dline];
- sline->init(2, &vertArray[i]);
- dline->init(INCREASING, sline);
- ret->insert(dline);
- index_dline++;
- }
- return ret;
-}
-#endif
-
-#if 0 // UNUSED
-static int num_edges(Bin& bin)
-{
- int sum=0;
- for(Arc_ptr jarc = bin.firstarc(); jarc; jarc=bin.nextarc())
- sum += jarc->pwlArc->npts-1;
- return sum;
-}
-#endif
-
-/*
-directedLine* bin_to_DLineLoops(Bin& bin)
-{
- directedLine *ret=NULL;
- directedLine *temp;
-
- int numedges = num_edges(bin);
- directedLine* dline_buf = new directedLine[numedges]; //not work for N32?
- sampledLine* sline_buf=new sampledLine[numedges];
-
- Real2* vertArray = new Real2[numedges*2];
- int index = 0;
- int index_dline = 0;
- bin.markall();
-
- for(Arc_ptr jarc = bin.firstarc(); jarc; jarc=bin.nextarc())
- {
- if(jarc->ismarked())
- {
- assert(jarc->check() != 0);
- Arc_ptr jarchead = jarc;
- do {
- jarc->clearmark();
- jarc = jarc->next;
- } while(jarc != jarchead);
- temp=copy_loop(jarchead, vertArray, index, dline_buf, sline_buf, index_dline);
- ret = temp->insertPolygon(ret);
- }
- }
-
- return ret;
-}
-*/
-
-
-directedLine* bin_to_DLineLoops(Bin& bin)
-{
- directedLine *ret=NULL;
- directedLine *temp;
- bin.markall();
- for(Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc()){
- if(jarc->ismarked()) {
- assert(jarc->check() != 0);
- Arc_ptr jarchead = jarc;
- do {
- jarc->clearmark();
- jarc = jarc->next;
- } while(jarc != jarchead);
- temp = arcLoopToDLineLoop(jarc);
- ret = temp->insertPolygon(ret);
- }
- }
- return ret;
-}
-
-directedLine* o_pwlcurve_to_DLines(directedLine* original, O_pwlcurve* pwl)
-{
- directedLine* ret = original;
- for(Int i=0; i<pwl->npts-1; i++)
- {
- sampledLine* sline = new sampledLine(2);
- sline->setPoint(0, pwl->pts[i].param);
- sline->setPoint(1, pwl->pts[i+1].param);
- directedLine* dline = new directedLine(INCREASING, sline);
- if(ret == NULL)
- ret = dline;
- else
- ret->insert(dline);
- }
- return ret;
-}
-
-directedLine* o_curve_to_DLineLoop(O_curve* cur)
-{
- directedLine *ret;
- if(cur == NULL)
- return NULL;
- assert(cur->curvetype == ct_pwlcurve);
- ret = o_pwlcurve_to_DLines(NULL, cur->curve.o_pwlcurve);
- for(O_curve* temp = cur->next; temp != NULL; temp = temp->next)
- {
- assert(temp->curvetype == ct_pwlcurve);
- ret = o_pwlcurve_to_DLines(ret, temp->curve.o_pwlcurve);
- }
- return ret;
-}
-
-directedLine* o_trim_to_DLineLoops(O_trim* trim)
-{
- O_trim* temp;
- directedLine *ret;
- if(trim == NULL)
- return NULL;
- ret = o_curve_to_DLineLoop(trim->o_curve);
-
- for(temp=trim->next; temp != NULL; temp = temp->next)
- {
- ret = ret->insertPolygon(o_curve_to_DLineLoop(temp->o_curve));
- }
- return ret;
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-#ifndef _DATA_TRANSFORM_H
-#define _DATA_TRANSFORM_H
-
-#include "reader.h"
-#include "directedLine.h"
-#include "bin.h"
-directedLine* bin_to_DLineLoops(Bin& bin);
-
-/*transform the pwlcurve into a number of directedline lines
- *insert these directedlines into orignal which is supposed to be
- *the part of the trimming loop obtained so far.
- *return the updated trimkming loop.
- */
-directedLine* o_pwlcurve_to_DLines(directedLine* original, O_pwlcurve* pwl);
-
-/*transform a trim loop (curve) into a directedLine loop
- */
-directedLine* o_curve_to_DLineLoop(O_curve* curve);
-
-/*transform a list of trim loops (trim) into
- *a list of polygons represented as directedLine*.
- */
-directedLine* o_trim_to_DLineLoops(O_trim* trim);
-
-
-#endif
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * defines.h
- *
- */
-
-#ifndef __gludefines_h_
-#define __gludefines_h_
-
-/* culling constants */
-#define CULL_TRIVIAL_REJECT 0
-#define CULL_TRIVIAL_ACCEPT 1
-#define CULL_ACCEPT 2
-
-/* maximum order of a B-Spline */
-#define MAXORDER 24
-
-/* maximum dimension of any B-spline range space */
-#define MAXCOORDS 5
-
-#endif /* __gludefines_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * displaylist.c++
- *
- */
-
-#include "glimports.h"
-#include "mystdio.h"
-#include "nurbstess.h"
-#include "displaylist.h"
-
-
-DisplayList::DisplayList( NurbsTessellator *_nt ) :
- dlnodePool( sizeof( Dlnode ), 1, "dlnodepool" )
-{
- lastNode = &nodes;
- nt = _nt;
-}
-
-DisplayList::~DisplayList( void )
-{
- for( Dlnode *nextNode; nodes; nodes = nextNode ) {
- nextNode = nodes->next;
- if( nodes->cleanup != 0 ) (nt->*nodes->cleanup)( nodes->arg );
- //nodes->deleteMe(dlnodePool);
- }
-}
-
-void
-DisplayList::play( void )
-{
- for( Dlnode *node = nodes; node; node = node->next )
- if( node->work != 0 ) (nt->*node->work)( node->arg );
-}
-
-void
-DisplayList::endList( void )
-{
- *lastNode = 0;
-}
-
-void
-DisplayList::append( PFVS work, void *arg, PFVS cleanup )
-{
- Dlnode *node = new(dlnodePool) Dlnode( work, arg, cleanup );
- *lastNode = node;
- lastNode = &(node->next);
-}
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * displaylist.h
- *
- */
-
-#ifndef __gludisplaylist_h_
-#define __gludisplaylist_h_
-
-#include "glimports.h"
-#include "mysetjmp.h"
-#include "mystdio.h"
-#include "bufpool.h"
-
-class NurbsTessellator;
-
-typedef void (NurbsTessellator::*PFVS)( void * );
-
-struct Dlnode : public PooledObj {
- Dlnode( PFVS, void *, PFVS );
- PFVS work;
- void * arg;
- PFVS cleanup;
- Dlnode * next;
-};
-
-inline
-Dlnode::Dlnode( PFVS _work, void *_arg, PFVS _cleanup )
-{
- work = _work;
- arg = _arg;
- cleanup = _cleanup;
- next = 0;
-}
-
-class DisplayList {
-public:
- DisplayList( NurbsTessellator * );
- ~DisplayList( void );
- void play( void );
- void append( PFVS work, void *arg, PFVS cleanup );
- void endList( void );
-private:
- Dlnode *nodes;
- Pool dlnodePool;
- Dlnode **lastNode;
- NurbsTessellator *nt;
-};
-
-#endif /* __gludisplaylist_h_ */
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-#ifndef __gludisplaymode_h_
-#define __gludisplaymode_h_
-
-#define N_MESHFILL 0
-#define N_MESHLINE 1
-#define N_MESHPOINT 2
-
-#endif /* __gludisplaymode_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * flist.c++
- *
- */
-
-#include "glimports.h"
-#include "myassert.h"
-#include "mystdio.h"
-#include "flist.h"
-
-/*----------------------------------------------------------------------------
- * Flist::Flist - initialize a REAL number array
- *----------------------------------------------------------------------------
- */
-Flist::Flist( void )
-{
- npts = 0;
- pts = 0;
- start = end = 0;
-}
-
-/*----------------------------------------------------------------------------
- * Flist::~Flist - free a REAL number array
- *----------------------------------------------------------------------------
- */
-Flist::~Flist( void )
-{
- if( npts ) delete[] pts;
-}
-
-void
-Flist::add( REAL x )
-{
- pts[end++] = x;
- assert( end <= npts );
-}
-
-/*----------------------------------------------------------------------------
- * Flist::filter - remove duplicate numbers from array
- *----------------------------------------------------------------------------
- */
-void Flist::filter( void )
-{
- sorter.qsort( pts, end );
- start = 0;
-
- int j = 0;
- for( int i = 1; i < end; i++ ) {
- if( pts[i] == pts[i-j-1] )
- j++;
- pts[i-j] = pts[i];
- }
- end -= j;
-}
-
-/*----------------------------------------------------------------------------
- * Flist::grow - ensure that array is large enough
- *----------------------------------------------------------------------------
- */
-void Flist::grow( int maxpts )
-{
- if( npts < maxpts ) {
- if( npts ) delete[] pts;
- npts = 2 * maxpts;
- pts = new REAL[npts];
- assert( pts != 0 );
- }
- start = end = 0;
-}
-
-/*----------------------------------------------------------------------------
- * Flist::taper - ignore head and tail of array
- *----------------------------------------------------------------------------
- */
-void Flist::taper( REAL from, REAL to )
-{
- while( pts[start] != from )
- start++;
-
- while( pts[end-1] != to )
- end--;
-}
-
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * flist.h
- *
- */
-
-#ifndef __gluflist_h_
-#define __gluflist_h_
-
-#include "types.h"
-#include "flistsorter.h"
-
-class Flist {
-public:
- REAL * pts; /* head of array */
- int npts; /* number of points in array */
- int start; /* first important point index */
- int end; /* last important point index */
-
- Flist( void );
- ~Flist( void );
- void add( REAL x );
- void filter( void );
- void grow( int);
- void taper( REAL , REAL );
-protected:
- FlistSorter sorter;
-};
-
-#endif /* __gluflist_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * flistsorter.c++
- *
- */
-
-#include "glimports.h"
-#include "flistsorter.h"
-
-FlistSorter::FlistSorter( void ) : Sorter( sizeof( REAL ) )
-{
-}
-
-void
-FlistSorter::qsort( REAL *p, int n )
-{
- Sorter::qsort( (char *)p, n );
-}
-
-int
-FlistSorter::qscmp( char *i, char *j )
-{
- REAL f0 = *(REAL *)i;
- REAL f1 = *(REAL *)j;
- return (f0 < f1) ? -1 : 1;
-}
-
-void
-FlistSorter::qsexc( char *i, char *j )
-{
- REAL *f0 = (REAL *)i;
- REAL *f1 = (REAL *)j;
- REAL tmp = *f0;
- *f0 = *f1;
- *f1 = tmp;
-}
-
-void
-FlistSorter::qstexc( char *i, char *j, char *k )
-{
- REAL *f0 = (REAL *)i;
- REAL *f1 = (REAL *)j;
- REAL *f2 = (REAL *)k;
- REAL tmp = *f0;
- *f0 = *f2;
- *f2 = *f1;
- *f1 = tmp;
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * flistsorter.h
- *
- */
-
-#ifndef __gluflistsorter_h_
-#define __gluflistsorter_h_
-
-#include "sorter.h"
-#include "types.h"
-
-class FlistSorter : public Sorter {
-public:
- FlistSorter(void);
- virtual ~FlistSorter() { /* silence warning*/ }
- void qsort( REAL *a, int n );
-
-protected:
- virtual int qscmp( char *, char * );
- virtual void qsexc( char *i, char *j ); // i<-j, j<-i
- virtual void qstexc( char *i, char *j, char *k ); // i<-k, k<-j, j<-i
-};
-#endif /* __gluflistsorter_h_ */
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * gridline.h
- *
- */
-
-#ifndef __glugridline_h_
-#define __glugridline_h_
-
-struct Gridline {
- long v;
- REAL vval;
- long vindex;
- long ustart;
- long uend;
- };
-#endif /* __glugridline_h_ */
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * gridtrimvertex.h
- *
- */
-
-#ifndef __glugridtrimvertex_h_
-#define __glugridtrimvertex_h_
-
-#include "mystdlib.h"
-#include "bufpool.h"
-#include "trimvertex.h"
-#include "gridvertex.h"
-
-class GridTrimVertex : public PooledObj
-{
-private:
- TrimVertex dummyt;
- GridVertex dummyg;
-public:
- GridTrimVertex() { g = 0; t = 0; }
- TrimVertex *t;
- GridVertex *g;
-
- inline void set( long, long );
- inline void set( REAL, REAL );
- inline void set( TrimVertex * );
- inline void clear( void ) { t = 0; g = 0; };
- inline int isGridVert() { return g ? 1 : 0 ; }
- inline int isTrimVert() { return t ? 1 : 0 ; }
- inline void output();
-};
-
-inline void
-GridTrimVertex::set( long x, long y )
-{
- g = &dummyg;
- dummyg.gparam[0] = x;
- dummyg.gparam[1] = y;
-}
-
-inline void
-GridTrimVertex::set( REAL x, REAL y )
-{
- g = 0;
- t = &dummyt;
- dummyt.param[0] = x;
- dummyt.param[1] = y;
- dummyt.nuid = 0;
-}
-
-inline void
-GridTrimVertex::set( TrimVertex *v )
-{
- g = 0;
- t = v;
-}
-
-typedef GridTrimVertex *GridTrimVertex_p;
-#endif /* __glugridtrimvertex_h_ */
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * gridvertex.h
- *
- */
-
-#ifndef __glugridvertex_h_
-#define __glugridvertex_h_
-
-struct GridVertex {
- long gparam[2];
- GridVertex( void ) { gparam[0] = 0, gparam[1] = 0; }
- GridVertex( long u, long v ) { gparam[0] = u, gparam[1] = v; }
- void set( long u, long v ) { gparam[0] = u, gparam[1] = v; }
- long nextu() { return gparam[0]++; }
- long prevu() { return gparam[0]--; }
-};
-
-#endif /* __glugridvertex_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * hull.c++
- *
- */
-
-#include "glimports.h"
-#include "myassert.h"
-#include "mystdio.h"
-#include "hull.h"
-#include "gridvertex.h"
-#include "gridtrimvertex.h"
-#include "gridline.h"
-#include "trimline.h"
-#include "uarray.h"
-#include "trimregion.h"
-
-Hull::Hull( void )
-{}
-
-Hull::~Hull( void )
-{}
-
-/*----------------------------------------------------------------------
- * Hull:init - this routine does the initialization needed before any
- * calls to nextupper or nextlower can be made.
- *----------------------------------------------------------------------
- */
-void
-Hull::init( void )
-{
- TrimVertex *lfirst = left.first();
- TrimVertex *llast = left.last();
- if( lfirst->param[0] <= llast->param[0] ) {
- fakeleft.init( left.first() );
- upper.left = &fakeleft;
- lower.left = &left;
- } else {
- fakeleft.init( left.last() );
- lower.left = &fakeleft;
- upper.left = &left;
- }
- upper.left->last();
- lower.left->first();
-
- if( top.ustart <= top.uend ) {
- upper.line = ⊤
- upper.index = top.ustart;
- } else
- upper.line = 0;
-
- if( bot.ustart <= bot.uend ) {
- lower.line = ⊥
- lower.index = bot.ustart;
- } else
- lower.line = 0;
-
- TrimVertex *rfirst = right.first();
- TrimVertex *rlast = right.last();
- if( rfirst->param[0] <= rlast->param[0] ) {
- fakeright.init( right.last() );
- lower.right = &fakeright;
- upper.right = &right;
- } else {
- fakeright.init( right.first() );
- upper.right = &fakeright;
- lower.right = &right;
- }
- upper.right->first();
- lower.right->last();
-}
-
-/*----------------------------------------------------------------------
- * nextupper - find next vertex on upper hull of trim region.
- * - if vertex is on trim curve, set vtop point to
- * that vertex. if vertex is on grid, set vtop to
- * point to temporary area and stuff coordinants into
- * temporary vertex. Also, place grid coords in temporary
- * grid vertex.
- *----------------------------------------------------------------------
- */
-GridTrimVertex *
-Hull::nextupper( GridTrimVertex *gv )
-{
- if( upper.left ) {
- gv->set( upper.left->prev() );
- if( gv->isTrimVert() ) return gv;
- upper.left = 0;
- }
-
- if( upper.line ) {
- assert( upper.index <= upper.line->uend );
- gv->set( uarray.uarray[upper.index], upper.line->vval );
- gv->set( upper.index, upper.line->vindex );
- if( upper.index++ == upper.line->uend ) upper.line = 0;
- return gv;
- }
-
- if( upper.right ) {
- gv->set( upper.right->next() );
- if( gv->isTrimVert() ) return gv;
- upper.right = 0;
- }
-
- return 0;
-}
-
-GridTrimVertex *
-Hull::nextlower( register GridTrimVertex *gv )
-{
- if( lower.left ) {
- gv->set( lower.left->next() );
- if( gv->isTrimVert() ) return gv;
- lower.left = 0;
- }
-
- if( lower.line ) {
- gv->set( uarray.uarray[lower.index], lower.line->vval );
- gv->set( lower.index, lower.line->vindex );
- if( lower.index++ == lower.line->uend ) lower.line = 0;
- return gv;
- }
-
- if( lower.right ) {
- gv->set( lower.right->prev() );
- if( gv->isTrimVert() ) return gv;
- lower.right = 0;
- }
-
- return 0;
-}
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * hull.h
- *
- */
-
-#ifndef __gluhull_h_
-#define __gluhull_h_
-
-#include "trimline.h"
-#include "trimregion.h"
-#include "trimvertex.h"
-#include "gridtrimvertex.h"
-
-struct Gridline;
-class Uarray;
-
-class Hull : virtual public TrimRegion {
-public:
- Hull( void );
- ~Hull( void );
- void init( void );
- GridTrimVertex * nextlower( GridTrimVertex * );
- GridTrimVertex * nextupper( GridTrimVertex * );
-private:
- struct Side {
- Trimline *left;
- Gridline *line;
- Trimline *right;
- long index;
- };
-
- Side lower;
- Side upper;
- Trimline fakeleft;
- Trimline fakeright;
-};
-
-
-#endif /* __gluhull_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * intersect.c++
- *
- */
-
-#include "glimports.h"
-#include "myassert.h"
-#include "mystdio.h"
-#include "subdivider.h"
-#include "arc.h"
-#include "bin.h"
-#include "backend.h"
-#include "trimvertpool.h"
-
-/*#define NOTDEF*/
-
-enum i_result { INTERSECT_VERTEX, INTERSECT_EDGE };
-
-/* local functions */
-#ifndef NDEBUG // for asserts only
-static int arc_classify( Arc_ptr, int, REAL );
-#endif
-static enum i_result pwlarc_intersect( PwlArc *, int, REAL, int, int[3] );
-
-
-void
-Subdivider::partition( Bin & bin, Bin & left, Bin & intersections,
- Bin & right, Bin & unknown, int param, REAL value )
-{
- Bin headonleft, headonright, tailonleft, tailonright;
-
- for( Arc_ptr jarc = bin.removearc(); jarc; jarc = bin.removearc() ) {
-
- REAL tdiff = jarc->tail()[param] - value;
- REAL hdiff = jarc->head()[param] - value;
-
- if( tdiff > 0.0 ) {
- if( hdiff > 0.0 ) {
- right.addarc( jarc );
- } else if( hdiff == 0.0 ) {
- tailonright.addarc( jarc );
- } else {
- Arc_ptr jtemp;
- switch( arc_split(jarc, param, value, 0) ) {
- case 2:
- tailonright.addarc( jarc );
- headonleft.addarc( jarc->next );
- break;
- case 31:
- assert( jarc->head()[param] > value );
- right.addarc( jarc );
- tailonright.addarc( jtemp = jarc->next );
- headonleft.addarc( jtemp->next );
- break;
- case 32:
- assert( jarc->head()[param] <= value );
- tailonright .addarc( jarc );
- headonleft.addarc( jtemp = jarc->next );
- left.addarc( jtemp->next );
- break;
- case 4:
- right.addarc( jarc );
- tailonright.addarc( jtemp = jarc->next );
- headonleft.addarc( jtemp = jtemp->next );
- left.addarc( jtemp->next );
- }
- }
- } else if( tdiff == 0.0 ) {
- if( hdiff > 0.0 ) {
- headonright.addarc( jarc );
- } else if( hdiff == 0.0 ) {
- unknown.addarc( jarc );
- } else {
- headonleft.addarc( jarc );
- }
- } else {
- if( hdiff > 0.0 ) {
- Arc_ptr jtemp;
- switch( arc_split(jarc, param, value, 1) ) {
- case 2:
- tailonleft.addarc( jarc );
- headonright.addarc( jarc->next );
- break;
- case 31:
- assert( jarc->head()[param] < value );
- left.addarc( jarc );
- tailonleft.addarc( jtemp = jarc->next );
- headonright.addarc( jtemp->next );
- break;
- case 32:
- assert( jarc->head()[param] >= value );
- tailonleft.addarc( jarc );
- headonright.addarc( jtemp = jarc->next );
- right.addarc( jtemp->next );
- break;
- case 4:
- left.addarc( jarc );
- tailonleft.addarc( jtemp = jarc->next );
- headonright.addarc( jtemp = jtemp->next );
- right.addarc( jtemp->next );
- }
- } else if( hdiff == 0.0 ) {
- tailonleft.addarc( jarc );
- } else {
- left.addarc( jarc );
- }
- }
- }
- if( param == 0 ) {
- classify_headonleft_s( headonleft, intersections, left, value );
- classify_tailonleft_s( tailonleft, intersections, left, value );
- classify_headonright_s( headonright, intersections, right, value );
- classify_tailonright_s( tailonright, intersections, right, value );
- } else {
- classify_headonleft_t( headonleft, intersections, left, value );
- classify_tailonleft_t( tailonleft, intersections, left, value );
- classify_headonright_t( headonright, intersections, right, value );
- classify_tailonright_t( tailonright, intersections, right, value );
- }
-}
-
-inline static void
-vert_interp( TrimVertex *n, TrimVertex *l, TrimVertex *r, int p, REAL val )
-{
- assert( val > l->param[p]);
- assert( val < r->param[p]);
-
- n->nuid = l->nuid;
-
- n->param[p] = val;
- if( l->param[1-p] != r->param[1-p] ) {
- REAL ratio = (val - l->param[p]) / (r->param[p] - l->param[p]);
- n->param[1-p] = l->param[1-p] +
- ratio * (r->param[1-p] - l->param[1-p]);
- } else {
- n->param[1-p] = l->param[1-p];
- }
-}
-
-int
-Subdivider::arc_split( Arc_ptr jarc, int param, REAL value, int dir )
-{
- int maxvertex = jarc->pwlArc->npts;
- Arc_ptr jarc1;
- TrimVertex* v = jarc->pwlArc->pts;
-
- int loc[3];
- switch( pwlarc_intersect( jarc->pwlArc, param, value, dir, loc ) ) {
-
- // When the parameter value lands on a vertex, life is sweet
- case INTERSECT_VERTEX: {
- jarc1 = new(arcpool) Arc( jarc, new( pwlarcpool) PwlArc( maxvertex-loc[1], &v[loc[1]] ) );
- jarc->pwlArc->npts = loc[1] + 1;
- jarc1->next = jarc->next;
- jarc1->next->prev = jarc1;
- jarc->next = jarc1;
- jarc1->prev = jarc;
- assert(jarc->check() != 0);
- return 2;
- }
-
- // When the parameter value intersects an edge, we have to
- // interpolate a new vertex. There are special cases
- // if the new vertex is adjacent to one or both of the
- // endpoints of the arc.
- case INTERSECT_EDGE: {
- int i, j;
- if( dir == 0 ) {
- i = loc[0];
- j = loc[2];
- } else {
- i = loc[2];
- j = loc[0];
- }
-
-#ifndef NOTDEF
- // The split is between vertices at index j and i, in that
- // order (j < i)
-
- // JEB: This code is my idea of how to do the split without
- // increasing the number of links. I'm doing this so that
- // the is_rect routine can recognize rectangles created by
- // subdivision. In exchange for simplifying the curve list,
- // however, it costs in allocated space and vertex copies.
-
- TrimVertex *newjunk = trimvertexpool.get(maxvertex -i+1 /*-j*/);
- int k;
- for(k=0; k<maxvertex-i; k++)
- {
- newjunk[k+1] = v[i+k];
- newjunk[k+1].nuid = jarc->nuid;
- }
-
- TrimVertex *vcopy = trimvertexpool.get(maxvertex);
- for(k=0; k<maxvertex; k++)
- {
- vcopy[k].param[0] = v[k].param[0];
- vcopy[k].param[1] = v[k].param[1];
- }
- jarc->pwlArc->pts=vcopy;
-
- v[i].nuid = jarc->nuid;
- v[j].nuid = jarc->nuid;
- vert_interp( &newjunk[0], &v[loc[0]], &v[loc[2]], param, value );
-
- if( showingDegenerate() )
- backend.triangle( &v[i], &newjunk[0], &v[j] );
-
- vcopy[j+1].param[0]=newjunk[0].param[0];
- vcopy[j+1].param[1]=newjunk[0].param[1];
-
-
- jarc1 = new(arcpool) Arc( jarc,
- new(pwlarcpool) PwlArc(maxvertex-i+1 , newjunk ) );
-
- jarc->pwlArc->npts = j+2;
- jarc1->next = jarc->next;
- jarc1->next->prev = jarc1;
- jarc->next = jarc1;
- jarc1->prev = jarc;
- assert(jarc->check() != 0);
-
- return 2;
-#endif //not NOTDEF
- // JEB: This is the original version:
-#ifdef NOTDEF
- Arc_ptr jarc2, jarc3;
-
- TrimVertex *newjunk = trimvertexpool.get(3);
- v[i].nuid = jarc->nuid;
- v[j].nuid = jarc->nuid;
- newjunk[0] = v[j];
- newjunk[2] = v[i];
- vert_interp( &newjunk[1], &v[loc[0]], &v[loc[2]], param, value );
-
- if( showingDegenerate() )
- backend.triangle( &newjunk[2], &newjunk[1], &newjunk[0] );
-
- // New vertex adjacent to both endpoints
- if (maxvertex == 2) {
- jarc1 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk+1 ) );
- jarc->pwlArc->npts = 2;
- jarc->pwlArc->pts = newjunk;
- jarc1->next = jarc->next;
- jarc1->next->prev = jarc1;
- jarc->next = jarc1;
- jarc1->prev = jarc;
- assert(jarc->check() != 0);
-
- return 2;
-
- // New vertex adjacent to ending point of arc
- } else if (maxvertex - j == 2) {
- jarc1 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk ) );
- jarc2 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk+1 ) );
- jarc->pwlArc->npts = maxvertex-1;
- jarc2->next = jarc->next;
- jarc2->next->prev = jarc2;
- jarc->next = jarc1;
- jarc1->prev = jarc;
- jarc1->next = jarc2;
- jarc2->prev = jarc1;
- assert(jarc->check() != 0);
- return 31;
-
- // New vertex adjacent to starting point of arc
- } else if (i == 1) {
- jarc1 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk+1 ) );
- jarc2 = new(arcpool) Arc( jarc,
- new(pwlarcpool) PwlArc( maxvertex-1, &jarc->pwlArc->pts[1] ) );
- jarc->pwlArc->npts = 2;
- jarc->pwlArc->pts = newjunk;
- jarc2->next = jarc->next;
- jarc2->next->prev = jarc2;
- jarc->next = jarc1;
- jarc1->prev = jarc;
- jarc1->next = jarc2;
- jarc2->prev = jarc1;
- assert(jarc->check() != 0);
- return 32;
-
- // It's somewhere in the middle
- } else {
- jarc1 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk ) );
- jarc2 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( 2, newjunk+1 ) );
- jarc3 = new(arcpool) Arc( jarc, new(pwlarcpool) PwlArc( maxvertex-i, v+i ) );
- jarc->pwlArc->npts = j + 1;
- jarc3->next = jarc->next;
- jarc3->next->prev = jarc3;
- jarc->next = jarc1;
- jarc1->prev = jarc;
- jarc1->next = jarc2;
- jarc2->prev = jarc1;
- jarc2->next = jarc3;
- jarc3->prev = jarc2;
- assert(jarc->check() != 0);
- return 4;
- }
-#endif // NOTDEF
- }
- default:
- return -1; //picked -1 since it's not used
- }
-}
-
-/*----------------------------------------------------------------------------
- * pwlarc_intersect - find intersection of pwlArc and isoparametric line
- *----------------------------------------------------------------------------
- */
-
-static enum i_result
-pwlarc_intersect(
- PwlArc *pwlArc,
- int param,
- REAL value,
- int dir,
- int loc[3] )
-{
- assert( pwlArc->npts > 0 );
-
- if( dir ) {
- TrimVertex *v = pwlArc->pts;
- int imin = 0;
- int imax = pwlArc->npts - 1;
- assert( value > v[imin].param[param] );
- assert( value < v[imax].param[param] );
- while( (imax - imin) > 1 ) {
- int imid = (imax + imin)/2;
- if( v[imid].param[param] > value )
- imax = imid;
- else if( v[imid].param[param] < value )
- imin = imid;
- else {
- loc[1] = imid;
- return INTERSECT_VERTEX;
- }
- }
- loc[0] = imin;
- loc[2] = imax;
- return INTERSECT_EDGE;
- } else {
- TrimVertex *v = pwlArc->pts;
- int imax = 0;
- int imin = pwlArc->npts - 1;
- assert( value > v[imin].param[param] );
- assert( value < v[imax].param[param] );
- while( (imin - imax) > 1 ) {
- int imid = (imax + imin)/2;
- if( v[imid].param[param] > value )
- imax = imid;
- else if( v[imid].param[param] < value )
- imin = imid;
- else {
- loc[1] = imid;
- return INTERSECT_VERTEX;
- }
- }
- loc[0] = imin;
- loc[2] = imax;
- return INTERSECT_EDGE;
- }
-}
-
-/*----------------------------------------------------------------------------
- * arc_classify - determine which side of a line a jarc lies
- *----------------------------------------------------------------------------
- */
-
-#ifndef NDEBUG // for asserts only
-static int
-arc_classify( Arc_ptr jarc, int param, REAL value )
-{
- REAL tdiff, hdiff;
- if( param == 0 ) {
- tdiff = jarc->tail()[0] - value;
- hdiff = jarc->head()[0] - value;
- } else {
- tdiff = jarc->tail()[1] - value;
- hdiff = jarc->head()[1] - value;
- }
-
- if( tdiff > 0.0 ) {
- if( hdiff > 0.0 ) {
- return 0x11;
- } else if( hdiff == 0.0 ) {
- return 0x12;
- } else {
- return 0x10;
- }
- } else if( tdiff == 0.0 ) {
- if( hdiff > 0.0 ) {
- return 0x21;
- } else if( hdiff == 0.0 ) {
- return 0x22;
- } else {
- return 0x20;
- }
- } else {
- if( hdiff > 0.0 ) {
- return 0x01;
- } else if( hdiff == 0.0 ) {
- return 0x02;
- } else {
- return 0;
- }
- }
-}
-#endif
-
-void
-Subdivider::classify_tailonleft_s( Bin& bin, Bin& in, Bin& out, REAL val )
-{
- /* tail at left, head on line */
- Arc_ptr j;
-
- while( (j = bin.removearc()) != NULL ) {
- assert( arc_classify( j, 0, val ) == 0x02 );
- j->clearitail();
-
- REAL diff = j->next->head()[0] - val;
- if( diff > 0.0 ) {
- in.addarc( j );
- } else if( diff < 0.0 ) {
- if( ccwTurn_sl( j, j->next ) )
- out.addarc( j );
- else
- in.addarc( j );
- } else {
- if( j->next->tail()[1] > j->next->head()[1] )
- in.addarc(j);
- else
- out.addarc(j);
- }
- }
-}
-
-void
-Subdivider::classify_tailonleft_t( Bin& bin, Bin& in, Bin& out, REAL val )
-{
- /* tail at left, head on line */
- Arc_ptr j;
-
- while( (j = bin.removearc()) != NULL ) {
- assert( arc_classify( j, 1, val ) == 0x02 );
- j->clearitail();
-
- REAL diff = j->next->head()[1] - val;
- if( diff > 0.0 ) {
- in.addarc( j );
- } else if( diff < 0.0 ) {
- if( ccwTurn_tl( j, j->next ) )
- out.addarc( j );
- else
- in.addarc( j );
- } else {
- if (j->next->tail()[0] > j->next->head()[0] )
- out.addarc( j );
- else
- in.addarc( j );
- }
- }
-}
-
-void
-Subdivider::classify_headonleft_s( Bin& bin, Bin& in, Bin& out, REAL val )
-{
- /* tail on line, head at left */
- Arc_ptr j;
-
- while( (j = bin.removearc()) != NULL ) {
- assert( arc_classify( j, 0, val ) == 0x20 );
-
- j->setitail();
-
- REAL diff = j->prev->tail()[0] - val;
- if( diff > 0.0 ) {
- out.addarc( j );
- } else if( diff < 0.0 ) {
- if( ccwTurn_sl( j->prev, j ) )
- out.addarc( j );
- else
- in.addarc( j );
- } else {
- if( j->prev->tail()[1] > j->prev->head()[1] )
- in.addarc( j );
- else
- out.addarc( j );
- }
- }
-}
-
-void
-Subdivider::classify_headonleft_t( Bin& bin, Bin& in, Bin& out, REAL val )
-{
- /* tail on line, head at left */
- Arc_ptr j;
-
- while( (j = bin.removearc()) != NULL ) {
- assert( arc_classify( j, 1, val ) == 0x20 );
- j->setitail();
-
- REAL diff = j->prev->tail()[1] - val;
- if( diff > 0.0 ) {
- out.addarc( j );
- } else if( diff < 0.0 ) {
- if( ccwTurn_tl( j->prev, j ) )
- out.addarc( j );
- else
- in.addarc( j );
- } else {
- if( j->prev->tail()[0] > j->prev->head()[0] )
- out.addarc( j );
- else
- in.addarc( j );
- }
- }
-}
-
-
-void
-Subdivider::classify_tailonright_s( Bin& bin, Bin& in, Bin& out, REAL val )
-{
- /* tail at right, head on line */
- Arc_ptr j;
-
- while( (j = bin.removearc()) != NULL ) {
- assert( arc_classify( j, 0, val ) == 0x12);
-
- j->clearitail();
-
- REAL diff = j->next->head()[0] - val;
- if( diff > 0.0 ) {
- if( ccwTurn_sr( j, j->next ) )
- out.addarc( j );
- else
- in.addarc( j );
- } else if( diff < 0.0 ) {
- in.addarc( j );
- } else {
- if( j->next->tail()[1] > j->next->head()[1] )
- out.addarc( j );
- else
- in.addarc( j );
- }
- }
-}
-
-void
-Subdivider::classify_tailonright_t( Bin& bin, Bin& in, Bin& out, REAL val )
-{
- /* tail at right, head on line */
- Arc_ptr j;
-
- while( (j = bin.removearc()) != NULL ) {
- assert( arc_classify( j, 1, val ) == 0x12);
-
- j->clearitail();
-
- REAL diff = j->next->head()[1] - val;
- if( diff > 0.0 ) {
- if( ccwTurn_tr( j, j->next ) )
- out.addarc( j );
- else
- in.addarc( j );
- } else if( diff < 0.0 ) {
- in.addarc( j );
- } else {
- if( j->next->tail()[0] > j->next->head()[0] )
- in.addarc( j );
- else
- out.addarc( j );
- }
- }
-}
-
-void
-Subdivider::classify_headonright_s( Bin& bin, Bin& in, Bin& out, REAL val )
-{
- /* tail on line, head at right */
- Arc_ptr j;
-
- while( (j = bin.removearc()) != NULL ) {
- assert( arc_classify( j, 0, val ) == 0x21 );
-
- j->setitail();
-
- REAL diff = j->prev->tail()[0] - val;
- if( diff > 0.0 ) {
- if( ccwTurn_sr( j->prev, j ) )
- out.addarc( j );
- else
- in.addarc( j );
- } else if( diff < 0.0 ) {
- out.addarc( j );
- } else {
- if( j->prev->tail()[1] > j->prev->head()[1] )
- out.addarc( j );
- else
- in.addarc( j );
- }
- }
-}
-
-void
-Subdivider::classify_headonright_t( Bin& bin, Bin& in, Bin& out, REAL val )
-{
- /* tail on line, head at right */
- Arc_ptr j;
-
- while( (j = bin.removearc()) != NULL ) {
- assert( arc_classify( j, 1, val ) == 0x21 );
-
- j->setitail();
-
- REAL diff = j->prev->tail()[1] - val;
- if( diff > 0.0 ) {
- if( ccwTurn_tr( j->prev, j ) )
- out.addarc( j );
- else
- in.addarc( j );
- } else if( diff < 0.0 ) {
- out.addarc( j );
- } else {
- if( j->prev->tail()[0] > j->prev->head()[0] )
- in.addarc( j );
- else
- out.addarc( j );
- }
- }
-}
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * jarcloc.h
- *
- */
-
-#ifndef __glujarcloc_h_
-#define __glujarcloc_h_
-
-#include "arc.h"
-
-class Jarcloc {
-private:
- Arc_ptr arc;
- TrimVertex *p;
- TrimVertex *plast;
-public:
- inline void init( Arc_ptr a, long first, long last ) { arc = a; p=&a->pwlArc->pts[first]; plast = &a->pwlArc->pts[last]; }
- inline TrimVertex * getnextpt( void );
- inline TrimVertex * getprevpt( void );
- inline void reverse();
-};
-
-inline void
-Jarcloc::reverse()
-{
- if( plast == &arc->pwlArc->pts[0] )
- plast = &arc->pwlArc->pts[arc->pwlArc->npts - 1];
- else
- plast = &arc->pwlArc->pts[0];
-}
-
-inline TrimVertex *
-Jarcloc::getnextpt()
-{
- assert( p <= plast );
- if( p == plast ) {
- arc = arc->next;
- p = &arc->pwlArc->pts[0];
- plast = &arc->pwlArc->pts[arc->pwlArc->npts - 1];
- assert( p < plast );
- }
- return p++;
-}
-
-inline TrimVertex *
-Jarcloc::getprevpt()
-{
- assert( p >= plast );
- if( p == plast ) {
- arc = arc->prev;
- p = &arc->pwlArc->pts[arc->pwlArc->npts - 1];
- plast = &arc->pwlArc->pts[0];
- assert( p > plast );
- }
- return p--;
-}
-#endif /* __glujarcloc_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * knotvector.c++
- *
- */
-
-#include "glimports.h"
-#include "mystdio.h"
-#include "myassert.h"
-#include "knotvector.h"
-#include "defines.h"
-
-#ifdef __WATCOMC__
-#pragma warning 726 10
-#endif
-
-void Knotvector::init( long _knotcount, long _stride, long _order, INREAL *_knotlist )
-{
- knotcount = _knotcount;
- stride = _stride;
- order = _order;
- knotlist = new Knot[_knotcount];
- assert( knotlist != 0 );
-
- for( int i = 0; i != _knotcount; i++ )
- knotlist[i] = (Knot) _knotlist[i];
-}
-
-Knotvector::Knotvector( void )
-{
- knotcount = 0;
- stride = 0;
- order = 0;
- knotlist = 0;
-}
-
-Knotvector::~Knotvector( void )
-{
- if( knotlist ) delete[] knotlist;
-}
-
-int Knotvector::validate( void )
-{
- /* kindex is used as an array index so subtract one first,
- * this propagates throughout the code so study carefully */
- long kindex = knotcount-1;
-
- if( order < 1 || order > MAXORDER ) {
- // spline order un-supported
- return( 1 );
- }
-
- if( knotcount < (2 * order) ) {
- // too few knots
- return( 2 );
- }
-
- if( identical( knotlist[kindex-(order-1)], knotlist[order-1]) ) {
- // valid knot range is empty
- return( 3 );
- }
-
- for( long i = 0; i < kindex; i++)
- if( knotlist[i] > knotlist[i+1] ) {
- // decreasing knot sequence
- return( 4 );
- }
-
- /* check for valid multiplicity */
-
- /* kindex is currently the index of the last knot.
- * In the next loop it is decremented to ignore the last knot
- * and the loop stops when kindex is 2 so as to ignore the first
- * knot as well. These knots are not used in computing
- * knot multiplicities.
- */
-
- long multi = 1;
- for( ; kindex >= 1; kindex-- ) {
- if( knotlist[kindex] - knotlist[kindex-1] < TOLERANCE ) {
- multi++;
- continue;
- }
- if ( multi > order ) {
- // knot multiplicity greater than order of spline
- return( 5 );
- }
- multi = 1;
- }
-
- if ( multi > order ) {
- // knot multiplicity greater than order of spline
- return( 5 );
- }
-
- return 0;
-}
-
-void Knotvector::show( const char *msg )
-{
-#ifndef NDEBUG
- _glu_dprintf( "%s\n", msg );
- _glu_dprintf( "order = %ld, count = %ld\n", order, knotcount );
-
- for( int i=0; i<knotcount; i++ )
- _glu_dprintf( "knot[%d] = %g\n", i, knotlist[i] );
-#endif
-}
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * knotvector.h
- *
- */
-
-#ifndef __gluknotvector_h_
-#define __gluknotvector_h_
-
-#include "types.h"
-
-struct Knotvector { /* a knot vector */
- Knotvector( void );
- ~Knotvector( void );
- void init( long, long, long, INREAL * );
- int validate( void );
- void show( const char * );
-
- long order; /* order of spline */
- long knotcount; /* number of knots */
- long stride; /* bytes between points */
- Knot * knotlist; /* global knot vector */
-};
-
-/* tolerance to test knot coincidence */
-#define TOLERANCE 1.0e-5
-
-inline int
-identical( Knot x, Knot y )
-{
- return ((x-y) < TOLERANCE) ? 1 : 0;
-}
-#endif /* __gluknotvector_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * mapdesc.c++
- *
- */
-
-#include <stdio.h>
-#include "glimports.h"
-#include "mystdio.h"
-#include "myassert.h"
-#include "mystring.h"
-#include "mymath.h"
-#include "backend.h"
-#include "nurbsconsts.h"
-#include "mapdesc.h"
-
-Mapdesc::Mapdesc( long _type, int _israt, int _ncoords, Backend& b )
- : backend( b )
-{
- type = _type;
- isrational = _israt;
- ncoords = _ncoords;
- hcoords = _ncoords + (_israt ? 0 : 1 );
- inhcoords = _ncoords - (_israt ? 1 : 0 );
- mask = ((1<<(inhcoords*2))-1);
- next = 0;
-
- assert( hcoords <= MAXCOORDS );
- assert( inhcoords >= 1 );
-
- pixel_tolerance = 1.0;
- error_tolerance = 1.0;
- bbox_subdividing = N_NOBBOXSUBDIVISION;
- culling_method = N_NOCULLING;
- sampling_method = N_NOSAMPLING;
- clampfactor = N_NOCLAMPING;
- minsavings = N_NOSAVINGSSUBDIVISION;
- s_steps = 0.0;
- t_steps = 0.0;
- maxrate = ( s_steps < 0.0 ) ? 0.0 : s_steps;
- maxsrate = ( s_steps < 0.0 ) ? 0.0 : s_steps;
- maxtrate = ( t_steps < 0.0 ) ? 0.0 : t_steps;
- identify( bmat );
- identify( cmat );
- identify( smat );
- for( int i = 0; i != inhcoords; i++ )
- bboxsize[i] = 1.0;
-}
-
-void
-Mapdesc::setBboxsize( INREAL *mat )
-{
- for( int i = 0; i != inhcoords; i++ )
- bboxsize[i] = (REAL) mat[i];
-}
-
-void
-Mapdesc::identify( REAL dest[MAXCOORDS][MAXCOORDS] )
-{
- memset( dest, 0, sizeof( REAL ) * MAXCOORDS * MAXCOORDS );
- for( int i=0; i != hcoords; i++ )
- dest[i][i] = 1.0;
-}
-
-void
-Mapdesc::surfbbox( REAL bb[2][MAXCOORDS] )
-{
- backend.surfbbox( type, bb[0], bb[1] );
-}
-
-void
-Mapdesc::copy( REAL dest[MAXCOORDS][MAXCOORDS], long n, INREAL *src,
- long rstride, long cstride )
-{
- assert( n >= 0 );
- for( int i=0; i != n; i++ )
- for( int j=0; j != n; j++ )
- dest[i][j] = src[i*rstride + j*cstride];
-}
-
-/*--------------------------------------------------------------------------
- * copyPt - copy a homogeneous point
- *--------------------------------------------------------------------------
- */
-void
-Mapdesc::copyPt( REAL *d, REAL *s )
-{
- assert( hcoords > 0 );
- switch( hcoords ) {
- case 4:
- d[3] = s[3];
- d[2] = s[2];
- d[1] = s[1];
- d[0] = s[0];
- break;
- case 3:
- d[2] = s[2];
- d[1] = s[1];
- d[0] = s[0];
- break;
- case 2:
- d[1] = s[1];
- d[0] = s[0];
- break;
- case 1:
- d[0] = s[0];
- break;
- case 5:
- d[4] = s[4];
- d[3] = s[3];
- d[2] = s[2];
- d[1] = s[1];
- d[0] = s[0];
- break;
- default:
- memcpy( d, s, hcoords * sizeof( REAL ) );
- break;
- }
-}
-
-/*--------------------------------------------------------------------------
- * sumPt - compute affine combination of two homogeneous points
- *--------------------------------------------------------------------------
- */
-void
-Mapdesc::sumPt( REAL *dst, REAL *src1, REAL *src2, register REAL alpha, register REAL beta )
-{
- assert( hcoords > 0 );
- switch( hcoords ) {
- case 4:
- dst[3] = src1[3] * alpha + src2[3] * beta;
- dst[2] = src1[2] * alpha + src2[2] * beta;
- dst[1] = src1[1] * alpha + src2[1] * beta;
- dst[0] = src1[0] * alpha + src2[0] * beta;
- break;
- case 3:
- dst[2] = src1[2] * alpha + src2[2] * beta;
- dst[1] = src1[1] * alpha + src2[1] * beta;
- dst[0] = src1[0] * alpha + src2[0] * beta;
- break;
- case 2:
- dst[1] = src1[1] * alpha + src2[1] * beta;
- dst[0] = src1[0] * alpha + src2[0] * beta;
- break;
- case 1:
- dst[0] = src1[0] * alpha + src2[0] * beta;
- break;
- case 5:
- dst[4] = src1[4] * alpha + src2[4] * beta;
- dst[3] = src1[3] * alpha + src2[3] * beta;
- dst[2] = src1[2] * alpha + src2[2] * beta;
- dst[1] = src1[1] * alpha + src2[1] * beta;
- dst[0] = src1[0] * alpha + src2[0] * beta;
- break;
- default: {
- for( int i = 0; i != hcoords; i++ )
- dst[i] = src1[i] * alpha + src2[i] * beta;
- }
- break;
- }
-}
-
-/*--------------------------------------------------------------------------
- * clipbits - compute bit-vector indicating point/window position
- * of a (transformed) homogeneous point
- *--------------------------------------------------------------------------
- */
-unsigned int
-Mapdesc::clipbits( REAL *p )
-{
- assert( inhcoords >= 0 );
- assert( inhcoords <= 3 );
-
- register int nc = inhcoords;
- register REAL pw = p[nc];
- register REAL nw = -pw;
- register unsigned int bits = 0;
-
- if( pw == 0.0 ) return mask;
-
- if( pw > 0.0 ) {
- switch( nc ) {
- case 3:
- if( p[2] <= pw ) bits |= (1<<5);
- if( p[2] >= nw ) bits |= (1<<4);
- if( p[1] <= pw ) bits |= (1<<3);
- if( p[1] >= nw ) bits |= (1<<2);
- if( p[0] <= pw ) bits |= (1<<1);
- if( p[0] >= nw ) bits |= (1<<0);
- return bits;
- case 2:
- if( p[1] <= pw ) bits |= (1<<3);
- if( p[1] >= nw ) bits |= (1<<2);
- if( p[0] <= pw ) bits |= (1<<1);
- if( p[0] >= nw ) bits |= (1<<0);
- return bits;
- case 1:
- if( p[0] <= pw ) bits |= (1<<1);
- if( p[0] >= nw ) bits |= (1<<0);
- return bits;
- default: {
- int bit = 1;
- for( int i=0; i<nc; i++ ) {
- if( p[i] >= nw ) bits |= bit;
- bit <<= 1;
- if( p[i] <= pw ) bits |= bit;
- bit <<= 1;
- }
- abort();
- break;
- }
- }
- } else {
- switch( nc ) {
- case 3:
- if( p[2] <= nw ) bits |= (1<<5);
- if( p[2] >= pw ) bits |= (1<<4);
- if( p[1] <= nw ) bits |= (1<<3);
- if( p[1] >= pw ) bits |= (1<<2);
- if( p[0] <= nw ) bits |= (1<<1);
- if( p[0] >= pw ) bits |= (1<<0);
- return bits;
- case 2:
- if( p[1] <= nw ) bits |= (1<<3);
- if( p[1] >= pw ) bits |= (1<<2);
- if( p[0] <= nw ) bits |= (1<<1);
- if( p[0] >= pw ) bits |= (1<<0);
- return bits;
- case 1:
- if( p[0] <= nw ) bits |= (1<<1);
- if( p[0] >= pw ) bits |= (1<<0);
- return bits;
- default: {
- int bit = 1;
- for( int i=0; i<nc; i++ ) {
- if( p[i] >= pw ) bits |= bit;
- bit <<= 1;
- if( p[i] <= nw ) bits |= bit;
- bit <<= 1;
- }
- abort();
- break;
- }
- }
- }
- return bits;
-}
-
-/*--------------------------------------------------------------------------
- * xformRational - transform a homogeneous point
- *--------------------------------------------------------------------------
- */
-void
-Mapdesc::xformRational( Maxmatrix mat, REAL *d, REAL *s )
-{
- assert( hcoords >= 0 );
-
- if( hcoords == 3 ) {
- REAL x = s[0];
- REAL y = s[1];
- REAL z = s[2];
- d[0] = x*mat[0][0]+y*mat[1][0]+z*mat[2][0];
- d[1] = x*mat[0][1]+y*mat[1][1]+z*mat[2][1];
- d[2] = x*mat[0][2]+y*mat[1][2]+z*mat[2][2];
- } else if( hcoords == 4 ) {
- REAL x = s[0];
- REAL y = s[1];
- REAL z = s[2];
- REAL w = s[3];
- d[0] = x*mat[0][0]+y*mat[1][0]+z*mat[2][0]+w*mat[3][0];
- d[1] = x*mat[0][1]+y*mat[1][1]+z*mat[2][1]+w*mat[3][1];
- d[2] = x*mat[0][2]+y*mat[1][2]+z*mat[2][2]+w*mat[3][2];
- d[3] = x*mat[0][3]+y*mat[1][3]+z*mat[2][3]+w*mat[3][3];
- } else {
- for( int i=0; i != hcoords; i++ ) {
- d[i] = 0;
- for( int j = 0; j != hcoords; j++ )
- d[i] += s[j] * mat[j][i];
- }
- }
-}
-
-/*--------------------------------------------------------------------------
- * xformNonrational - transform a inhomogeneous point to a homogeneous point
- *--------------------------------------------------------------------------
- */
-void
-Mapdesc::xformNonrational( Maxmatrix mat, REAL *d, REAL *s )
-{
- if( inhcoords == 2 ) {
- REAL x = s[0];
- REAL y = s[1];
- d[0] = x*mat[0][0]+y*mat[1][0]+mat[2][0];
- d[1] = x*mat[0][1]+y*mat[1][1]+mat[2][1];
- d[2] = x*mat[0][2]+y*mat[1][2]+mat[2][2];
- } else if( inhcoords == 3 ) {
- REAL x = s[0];
- REAL y = s[1];
- REAL z = s[2];
- d[0] = x*mat[0][0]+y*mat[1][0]+z*mat[2][0]+mat[3][0];
- d[1] = x*mat[0][1]+y*mat[1][1]+z*mat[2][1]+mat[3][1];
- d[2] = x*mat[0][2]+y*mat[1][2]+z*mat[2][2]+mat[3][2];
- d[3] = x*mat[0][3]+y*mat[1][3]+z*mat[2][3]+mat[3][3];
- } else {
- assert( inhcoords >= 0 );
- for( int i=0; i != hcoords; i++ ) {
- d[i] = mat[inhcoords][i];
- for( int j = 0; j < inhcoords; j++ )
- d[i] += s[j] * mat[j][i];
- }
- }
-}
-
-/*--------------------------------------------------------------------------
- * xformAndCullCheck - transform a set of points that may be EITHER
- * homogeneous or inhomogeneous depending on the map description and
- * check if they are either completely inside, completely outside,
- * or intersecting the viewing frustrum.
- *--------------------------------------------------------------------------
- */
-int
-Mapdesc::xformAndCullCheck(
- REAL *pts, int uorder, int ustride, int vorder, int vstride )
-{
- assert( uorder > 0 );
- assert( vorder > 0 );
-
- unsigned int inbits = mask;
- unsigned int outbits = 0;
-
- REAL *p = pts;
- for( REAL *pend = p + uorder * ustride; p != pend; p += ustride ) {
- REAL *q = p;
- for( REAL *qend = q + vorder * vstride; q != qend; q += vstride ) {
- REAL cpts[MAXCOORDS];
- xformCulling( cpts, q );
- unsigned int bits = clipbits( cpts );
- outbits |= bits;
- inbits &= bits;
- if( ( outbits == (unsigned int)mask ) && ( inbits != (unsigned int)mask ) ) return CULL_ACCEPT;
- }
- }
-
- if( outbits != (unsigned int)mask ) {
- return CULL_TRIVIAL_REJECT;
- } else if( inbits == (unsigned int)mask ) {
- return CULL_TRIVIAL_ACCEPT;
- } else {
- return CULL_ACCEPT;
- }
-}
-
-/*--------------------------------------------------------------------------
- * cullCheck - check if a set of homogeneous transformed points are
- * either completely inside, completely outside,
- * or intersecting the viewing frustrum.
- *--------------------------------------------------------------------------
- */
-int
-Mapdesc::cullCheck( REAL *pts, int uorder, int ustride, int vorder, int vstride )
-{
- unsigned int inbits = mask;
- unsigned int outbits = 0;
-
- REAL *p = pts;
- for( REAL *pend = p + uorder * ustride; p != pend; p += ustride ) {
- REAL *q = p;
- for( REAL *qend = q + vorder * vstride; q != qend; q += vstride ) {
- unsigned int bits = clipbits( q );
- outbits |= bits;
- inbits &= bits;
- if( ( outbits == (unsigned int)mask ) && ( inbits != (unsigned int)mask ) ) return CULL_ACCEPT;
- }
- }
-
- if( outbits != (unsigned int)mask ) {
- return CULL_TRIVIAL_REJECT;
- } else if( inbits == (unsigned int)mask ) {
- return CULL_TRIVIAL_ACCEPT;
- } else {
- return CULL_ACCEPT;
- }
-}
-
-/*--------------------------------------------------------------------------
- * cullCheck - check if a set of homogeneous transformed points are
- * either completely inside, completely outside,
- * or intersecting the viewing frustrum.
- *--------------------------------------------------------------------------
- */
-int
-Mapdesc::cullCheck( REAL *pts, int order, int stride )
-{
- unsigned int inbits = mask;
- unsigned int outbits = 0;
-
- REAL *p = pts;
- for( REAL *pend = p + order * stride; p != pend; p += stride ) {
- unsigned int bits = clipbits( p );
- outbits |= bits;
- inbits &= bits;
- if( ( outbits == (unsigned int)mask ) && ( inbits != (unsigned int)mask ) ) return CULL_ACCEPT;
- }
-
- if( outbits != (unsigned int)mask ) {
- return CULL_TRIVIAL_REJECT;
- } else if( inbits == (unsigned int)mask ) {
- return CULL_TRIVIAL_ACCEPT;
- } else {
- return CULL_ACCEPT;
- }
-}
-
-/*--------------------------------------------------------------------------
- * xformSampling - transform a set of points that may be EITHER
- * homogeneous or inhomogeneous depending on the map description
- * into sampling space
- *--------------------------------------------------------------------------
- */
-void
-Mapdesc::xformSampling( REAL *pts, int order, int stride, REAL *sp, int outstride )
-{
- xformMat( smat, pts, order, stride, sp, outstride );
-}
-
-void
-Mapdesc::xformBounding( REAL *pts, int order, int stride, REAL *sp, int outstride )
-{
- xformMat( bmat, pts, order, stride, sp, outstride );
-}
-
-/*--------------------------------------------------------------------------
- * xformCulling - transform a set of points that may be EITHER
- * homogeneous or inhomogeneous depending on the map description
- * into culling space
- *--------------------------------------------------------------------------
- */
-void
-Mapdesc::xformCulling( REAL *pts, int order, int stride, REAL *cp, int outstride )
-{
- xformMat( cmat, pts, order, stride, cp, outstride );
-}
-
-/*--------------------------------------------------------------------------
- * xformCulling - transform a set of points that may be EITHER
- * homogeneous or inhomogeneous depending on the map description
- * into culling space
- *--------------------------------------------------------------------------
- */
-void
-Mapdesc::xformCulling( REAL *pts,
- int uorder, int ustride,
- int vorder, int vstride,
- REAL *cp, int outustride, int outvstride )
-{
- xformMat( cmat, pts, uorder, ustride, vorder, vstride, cp, outustride, outvstride );
-}
-
-/*--------------------------------------------------------------------------
- * xformSampling - transform a set of points that may be EITHER
- * homogeneous or inhomogeneous depending on the map description
- * into sampling space
- *--------------------------------------------------------------------------
- */
-void
-Mapdesc::xformSampling( REAL *pts,
- int uorder, int ustride,
- int vorder, int vstride,
- REAL *sp, int outustride, int outvstride )
-{
- xformMat( smat, pts, uorder, ustride, vorder, vstride, sp, outustride, outvstride );
-}
-
-void
-Mapdesc::xformBounding( REAL *pts,
- int uorder, int ustride,
- int vorder, int vstride,
- REAL *sp, int outustride, int outvstride )
-{
- xformMat( bmat, pts, uorder, ustride, vorder, vstride, sp, outustride, outvstride );
-}
-
-void
-Mapdesc::xformMat(
- Maxmatrix mat,
- REAL * pts,
- int order,
- int stride,
- REAL * cp,
- int outstride )
-{
- if( isrational ) {
- REAL *pend = pts + order * stride;
- for( REAL *p = pts ; p != pend; p += stride ) {
- xformRational( mat, cp, p );
- cp += outstride;
- }
- } else {
- REAL *pend = pts + order * stride;
- for( REAL *p = pts ; p != pend; p += stride ) {
- xformNonrational( mat, cp, p );
- cp += outstride;
- }
- }
-}
-
-void
-Mapdesc::xformMat( Maxmatrix mat, REAL *pts,
- int uorder, int ustride,
- int vorder, int vstride,
- REAL *cp, int outustride, int outvstride )
-{
- if( isrational ) {
- REAL *pend = pts + uorder * ustride;
- for( REAL *p = pts ; p != pend; p += ustride ) {
- REAL *cpts2 = cp;
- REAL *qend = p + vorder * vstride;
- for( REAL *q = p; q != qend; q += vstride ) {
- xformRational( mat, cpts2, q );
- cpts2 += outvstride;
- }
- cp += outustride;
- }
- } else {
- REAL *pend = pts + uorder * ustride;
- for( REAL *p = pts ; p != pend; p += ustride ) {
- REAL *cpts2 = cp;
- REAL *qend = p + vorder * vstride;
- for( REAL *q = p; q != qend; q += vstride ) {
- xformNonrational( mat, cpts2, q );
- cpts2 += outvstride;
- }
- cp += outustride;
- }
- }
-}
-
-/*--------------------------------------------------------------------------
- * subdivide - subdivide a curve along an isoparametric line
- *--------------------------------------------------------------------------
- */
-
-void
-Mapdesc::subdivide( REAL *src, REAL *dst, REAL v, int stride, int order )
-{
- REAL mv = 1.0 - v;
-
- for( REAL *send=src+stride*order; src!=send; send-=stride, dst+=stride ) {
- copyPt( dst, src );
- REAL *qpnt = src + stride;
- for( REAL *qp=src; qpnt!=send; qp=qpnt, qpnt+=stride )
- sumPt( qp, qp, qpnt, mv, v );
- }
-}
-
-/*--------------------------------------------------------------------------
- * subdivide - subdivide a patch along an isoparametric line
- *--------------------------------------------------------------------------
- */
-
-void
-Mapdesc::subdivide( REAL *src, REAL *dst, REAL v,
- int so, int ss, int to, int ts )
-{
- REAL mv = 1.0 - v;
-
- for( REAL *slast = src+ss*so; src != slast; src += ss, dst += ss ) {
- REAL *sp = src;
- REAL *dp = dst;
- for( REAL *send = src+ts*to; sp != send; send -= ts, dp += ts ) {
- copyPt( dp, sp );
- REAL *qp = sp;
- for( REAL *qpnt = sp+ts; qpnt != send; qp = qpnt, qpnt += ts )
- sumPt( qp, qp, qpnt, mv, v );
- }
- }
-}
-
-
-#define sign(x) ((x > 0) ? 1 : ((x < 0.0) ? -1 : 0))
-
-/*--------------------------------------------------------------------------
- * project - project a set of homogeneous coordinates into inhomogeneous ones
- *--------------------------------------------------------------------------
- */
-int
-Mapdesc::project( REAL *src, int rstride, int cstride,
- REAL *dest, int trstride, int tcstride,
- int nrows, int ncols )
-{
- int s = sign( src[inhcoords] );
- REAL *rlast = src + nrows * rstride;
- REAL *trptr = dest;
- for( REAL *rptr=src; rptr != rlast; rptr+=rstride, trptr+=trstride ) {
- REAL *clast = rptr + ncols * cstride;
- REAL *tcptr = trptr;
- for( REAL *cptr = rptr; cptr != clast; cptr+=cstride, tcptr+=tcstride ) {
- REAL *coordlast = cptr + inhcoords;
- if( sign( *coordlast ) != s ) return 0;
- REAL *tcoord = tcptr;
- for( REAL *coord = cptr; coord != coordlast; coord++, tcoord++ ) {
- *tcoord = *coord / *coordlast;
- }
- }
- }
- return 1;
-}
-
-/*--------------------------------------------------------------------------
- * project - project a set of homogeneous coordinates into inhomogeneous ones
- *--------------------------------------------------------------------------
- */
-int
-Mapdesc::project( REAL *src, int stride, REAL *dest, int tstride, int ncols )
-{
- int s = sign( src[inhcoords] );
-
- REAL *clast = src + ncols * stride;
- for( REAL *cptr = src, *tcptr = dest; cptr != clast; cptr+=stride, tcptr+=tstride ) {
- REAL *coordlast = cptr + inhcoords;
- if( sign( *coordlast ) != s ) return 0;
- for( REAL *coord = cptr, *tcoord = tcptr; coord != coordlast; coord++, tcoord++ )
- *tcoord = *coord / *coordlast;
- }
-
- return 1;
-}
-
-int
-Mapdesc::bboxTooBig(
- REAL *p,
- int rstride,
- int cstride,
- int nrows,
- int ncols,
- REAL bb[2][MAXCOORDS] )
-{
- REAL bbpts[MAXORDER][MAXORDER][MAXCOORDS];
- const int trstride = sizeof(bbpts[0]) / sizeof(REAL);
- const int tcstride = sizeof(bbpts[0][0]) / sizeof(REAL);
-
- // points have been transformed, therefore they are homogeneous
- // project points
- int val = project( p, rstride, cstride,
- &bbpts[0][0][0], trstride, tcstride, nrows, ncols );
- if( val == 0 ) return -1;
-
- // compute bounding box
- bbox( bb, &bbpts[0][0][0], trstride, tcstride, nrows, ncols );
-
- // find out if bounding box can't fit in unit cube
- if( bbox_subdividing == N_BBOXROUND ) {
- for( int k=0; k != inhcoords; k++ )
- if( ceilf(bb[1][k]) - floorf(bb[0][k]) > bboxsize[k] ) return 1;
- } else {
- for( int k=0; k != inhcoords; k++ )
- if( bb[1][k] - bb[0][k] > bboxsize[k] ) return 1;
- }
- return 0;
-}
-
-void
-Mapdesc::bbox(
- REAL bb[2][MAXCOORDS],
- REAL *p,
- int rstride,
- int cstride,
- int nrows,
- int ncols )
-{
- int k;
- for( k=0; k != inhcoords; k++ )
- bb[0][k] = bb[1][k] = p[k];
-
- for( int i=0; i != nrows; i++ )
- for( int j=0; j != ncols; j++ )
- for( k=0; k != inhcoords; k++ ) {
- REAL x = p[i*rstride + j*cstride + k];
- if( x < bb[0][k] ) bb[0][k] = x;
- else if( x > bb[1][k] ) bb[1][k] = x;
- }
-}
-
-/*--------------------------------------------------------------------------
- * calcVelocityRational - calculate upper bound on first partial derivative
- * of a homogeneous set of points and bounds on each row of points.
- *--------------------------------------------------------------------------
- */
-REAL
-Mapdesc::calcVelocityRational( REAL *p, int stride, int ncols )
-{
- REAL tmp[MAXORDER][MAXCOORDS];
-
- assert( ncols <= MAXORDER );
-
- const int tstride = sizeof(tmp[0]) / sizeof(REAL);
-
- if( project( p, stride, &tmp[0][0], tstride, ncols ) ) {
- return calcPartialVelocity( &tmp[0][0], tstride, ncols, 1, 1.0 );
- } else { /* XXX */
- return calcPartialVelocity( &tmp[0][0], tstride, ncols, 1, 1.0 );
- }
-}
-
-/*--------------------------------------------------------------------------
- * calcVelocityNonrational - calculate upper bound on first partial
- * derivative of a inhomogeneous set of points.
- *--------------------------------------------------------------------------
- */
-REAL
-Mapdesc::calcVelocityNonrational( REAL *pts, int stride, int ncols )
-{
- return calcPartialVelocity( pts, stride, ncols, 1, 1.0 );
-}
-
-int
-Mapdesc::isProperty( long property )
-{
- switch ( property ) {
- case N_PIXEL_TOLERANCE:
- case N_ERROR_TOLERANCE:
- case N_CULLING:
- case N_BBOX_SUBDIVIDING:
- case N_S_STEPS:
- case N_T_STEPS:
- case N_SAMPLINGMETHOD:
- case N_CLAMPFACTOR:
- case N_MINSAVINGS:
- return 1;
- default:
- return 0;
- }
-}
-
-REAL
-Mapdesc::getProperty( long property )
-{
- switch ( property ) {
- case N_PIXEL_TOLERANCE:
- return pixel_tolerance;
- case N_ERROR_TOLERANCE:
- return error_tolerance;
- case N_CULLING:
- return culling_method;
- case N_BBOX_SUBDIVIDING:
- return bbox_subdividing;
- case N_S_STEPS:
- return s_steps;
- case N_T_STEPS:
- return t_steps;
- case N_SAMPLINGMETHOD:
- return sampling_method;
- case N_CLAMPFACTOR:
- return clampfactor;
- case N_MINSAVINGS:
- return minsavings;
- default:
- abort();
- return -1; //not necessary, needed to shut up compiler
- }
-}
-
-void
-Mapdesc::setProperty( long property, REAL value )
-{
-
- switch ( property ) {
- case N_PIXEL_TOLERANCE:
- pixel_tolerance = value;
- break;
- case N_ERROR_TOLERANCE:
- error_tolerance = value;
- break;
- case N_CULLING:
- culling_method = value;
- break;
- case N_BBOX_SUBDIVIDING:
- if( value <= 0.0 ) value = N_NOBBOXSUBDIVISION;
- bbox_subdividing = value;
- break;
- case N_S_STEPS:
- if( value < 0.0 ) value = 0.0;
- s_steps = value;
- maxrate = ( value < 0.0 ) ? 0.0 : value;
- maxsrate = ( value < 0.0 ) ? 0.0 : value;
- break;
- case N_T_STEPS:
- if( value < 0.0 ) value = 0.0;
- t_steps = value;
- maxtrate = ( value < 0.0 ) ? 0.0 : value;
- break;
- case N_SAMPLINGMETHOD:
- sampling_method = value;
- break;
- case N_CLAMPFACTOR:
- if( value <= 0.0 ) value = N_NOCLAMPING;
- clampfactor = value;
- break;
- case N_MINSAVINGS:
- if( value <= 0.0 ) value = N_NOSAVINGSSUBDIVISION;
- minsavings = value;
- break;
- default:
- abort();
- break;
- }
-}
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * mapdesc.h
- *
- */
-
-#ifndef __glumapdesc_h_
-#define __glumapdesc_h_
-
-#include "mystdio.h"
-#include "types.h"
-#include "defines.h"
-#include "bufpool.h"
-#include "nurbsconsts.h"
-
-typedef REAL Maxmatrix[MAXCOORDS][MAXCOORDS];
-
-class Backend;
-
-class Mapdesc : public PooledObj {
- friend class Maplist;
-
-public:
- Mapdesc( long, int, int, Backend & );
- int isProperty( long );
- REAL getProperty( long );
- void setProperty( long, REAL );
- int isConstantSampling( void );
- int isDomainSampling( void );
- int isRangeSampling( void );
- int isSampling( void );
- int isParametricDistanceSampling( void );
- int isObjectSpaceParaSampling( void );
- int isObjectSpacePathSampling( void );
- int isSurfaceAreaSampling( void );
- int isPathLengthSampling( void );
- int isCulling( void );
- int isBboxSubdividing( void );
- long getType( void );
-
- /* curve routines */
- void subdivide( REAL *, REAL *, REAL, int, int );
- int cullCheck( REAL *, int, int );
- void xformBounding( REAL *, int, int, REAL *, int );
- void xformCulling( REAL *, int, int, REAL *, int );
- void xformSampling( REAL *, int, int, REAL *, int );
- void xformMat( Maxmatrix, REAL *, int, int, REAL *, int );
- REAL calcPartialVelocity ( REAL *, int, int, int, REAL );
- int project( REAL *, int, REAL *, int, int );
- REAL calcVelocityRational( REAL *, int, int );
- REAL calcVelocityNonrational( REAL *, int, int );
-
- /* surface routines */
- void subdivide( REAL *, REAL *, REAL, int, int, int, int );
- int cullCheck( REAL *, int, int, int, int );
- void xformBounding( REAL *, int, int, int, int, REAL *, int, int );
- void xformCulling( REAL *, int, int, int, int, REAL *, int, int );
- void xformSampling( REAL *, int, int, int, int, REAL *, int, int );
- void xformMat( Maxmatrix, REAL *, int, int, int, int, REAL *, int, int );
- REAL calcPartialVelocity ( REAL *, REAL *, int, int, int, int, int, int, REAL, REAL, int );
- int project( REAL *, int, int, REAL *, int, int, int, int);
- void surfbbox( REAL bb[2][MAXCOORDS] );
-
- int bboxTooBig( REAL *, int, int, int, int, REAL [2][MAXCOORDS] );
- int xformAndCullCheck( REAL *, int, int, int, int );
-
- void identify( REAL[MAXCOORDS][MAXCOORDS] );
- void setBboxsize( INREAL *);
- inline void setBmat( INREAL*, long, long );
- inline void setCmat( INREAL*, long, long );
- inline void setSmat( INREAL*, long, long );
- inline int isRational( void );
- inline int getNcoords( void );
-
- REAL pixel_tolerance; /* pathlength sampling tolerance */
- REAL error_tolerance; /* parametric error sampling tolerance*/
- REAL object_space_error_tolerance; /* object space tess*/
- REAL clampfactor;
- REAL minsavings;
- REAL maxrate;
- REAL maxsrate;
- REAL maxtrate;
- REAL bboxsize[MAXCOORDS];
-
-private:
- long type;
- int isrational;
- int ncoords;
- int hcoords;
- int inhcoords;
- int mask;
- Maxmatrix bmat;
- Maxmatrix cmat;
- Maxmatrix smat;
- REAL s_steps; /* max samples in s direction */
- REAL t_steps; /* max samples in t direction */
- REAL sampling_method;
- REAL culling_method; /* check for culling */
- REAL bbox_subdividing;
- Mapdesc * next;
- Backend & backend;
-
- void bbox( REAL [2][MAXCOORDS], REAL *, int, int, int, int );
- REAL maxDifference( int, REAL *, int );
- static void copy( Maxmatrix, long, INREAL *, long, long );
-
- /* individual control point routines */
- static void transform4d( float[4], float[4], float[4][4] );
- static void multmatrix4d ( float[4][4], const float[4][4],
- const float[4][4] );
- void copyPt( REAL *, REAL * );
- void sumPt( REAL *, REAL *, REAL *, REAL, REAL );
- void xformSampling( REAL *, REAL * );
- void xformCulling( REAL *, REAL * );
- void xformRational( Maxmatrix, REAL *, REAL * );
- void xformNonrational( Maxmatrix, REAL *, REAL * );
- unsigned int clipbits( REAL * );
-};
-
-inline void
-Mapdesc::setBmat( INREAL *mat, long rstride, long cstride )
-{
- copy( bmat, hcoords, mat, rstride, cstride );
-}
-
-inline void
-Mapdesc::setCmat( INREAL *mat, long rstride, long cstride )
-{
- copy( cmat, hcoords, mat, rstride, cstride );
-}
-
-inline void
-Mapdesc::setSmat( INREAL *mat, long rstride, long cstride )
-{
- copy( smat, hcoords, mat, rstride, cstride );
-}
-
-inline long
-Mapdesc::getType( void )
-{
- return type;
-}
-
-inline void
-Mapdesc::xformCulling( REAL *d, REAL *s )
-{
- if( isrational )
- xformRational( cmat, d, s );
- else
- xformNonrational( cmat, d, s );
-}
-
-inline void
-Mapdesc::xformSampling( REAL *d, REAL *s )
-{
- if( isrational )
- xformRational( smat, d, s );
- else
- xformNonrational( smat, d, s );
-}
-
-inline int
-Mapdesc::isRational( void )
-{
- return isrational ? 1 : 0;
-}
-
-inline int
-Mapdesc::getNcoords( void )
-{
- return ncoords;
-}
-
-inline int
-Mapdesc::isConstantSampling( void )
-{
- return ((sampling_method == N_FIXEDRATE) ? 1 : 0);
-}
-
-inline int
-Mapdesc::isDomainSampling( void )
-{
- return ((sampling_method == N_DOMAINDISTANCE) ? 1 : 0);
-}
-
-inline int
-Mapdesc::isParametricDistanceSampling( void )
-{
- return ((sampling_method == N_PARAMETRICDISTANCE) ? 1 : 0);
-}
-
-inline int
-Mapdesc::isObjectSpaceParaSampling( void )
-{
- return ((sampling_method == N_OBJECTSPACE_PARA) ? 1 : 0);
-}
-
-inline int
-Mapdesc::isObjectSpacePathSampling( void )
-{
- return ((sampling_method == N_OBJECTSPACE_PATH) ? 1 : 0);
-}
-
-inline int
-Mapdesc::isSurfaceAreaSampling( void )
-{
- return ((sampling_method == N_SURFACEAREA) ? 1 : 0);
-}
-
-inline int
-Mapdesc::isPathLengthSampling( void )
-{
- return ((sampling_method == N_PATHLENGTH) ? 1 : 0);
-}
-
-inline int
-Mapdesc::isRangeSampling( void )
-{
- return ( isParametricDistanceSampling() || isPathLengthSampling() ||
- isSurfaceAreaSampling() ||
- isObjectSpaceParaSampling() ||
- isObjectSpacePathSampling());
-}
-
-inline int
-Mapdesc::isSampling( void )
-{
- return isRangeSampling() || isConstantSampling() || isDomainSampling();
-}
-
-inline int
-Mapdesc::isCulling( void )
-{
- return ((culling_method != N_NOCULLING) ? 1 : 0);
-}
-
-inline int
-Mapdesc::isBboxSubdividing( void )
-{
- return ((bbox_subdividing != N_NOBBOXSUBDIVISION) ? 1 : 0);
-}
-#endif /* __glumapdesc_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * mapdescv.c++
- *
- */
-
-#include "glimports.h"
-#include "mystdio.h"
-#include "myassert.h"
-#include "mystring.h"
-#include "mymath.h"
-#include "nurbsconsts.h"
-#include "mapdesc.h"
-
-/*--------------------------------------------------------------------------
- * calcPartialVelocity - calculate maximum magnitude of a given partial
- * derivative
- *--------------------------------------------------------------------------
- */
-REAL
-Mapdesc::calcPartialVelocity (
- REAL *p,
- int stride,
- int ncols,
- int partial,
- REAL range )
-{
- REAL tmp[MAXORDER][MAXCOORDS];
- REAL mag[MAXORDER];
-
- assert( ncols <= MAXORDER );
-
- int j, k, t;
- // copy inhomogeneous control points into temporary array
- for( j=0; j != ncols; j++ )
- for( k=0; k != inhcoords; k++ )
- tmp[j][k] = p[j*stride + k];
-
- for( t=0; t != partial; t++ )
- for( j=0; j != ncols-t-1; j++ )
- for( k=0; k != inhcoords; k++ )
- tmp[j][k] = tmp[j+1][k] - tmp[j][k];
-
- // compute magnitude and store in mag array
- for( j=0; j != ncols-partial; j++ ) {
- mag[j] = 0.0;
- for( k=0; k != inhcoords; k++ )
- mag[j] += tmp[j][k] * tmp[j][k];
- }
-
- // compute scale factor
- REAL fac = 1;
- REAL invt = 1.0 / range;
- for( t = ncols-1; t != ncols-1-partial; t-- )
- fac *= t * invt;
-
- // compute max magnitude of all entries in array
- REAL max = 0.0;
- for( j=0; j != ncols-partial; j++ )
- if( mag[j] > max ) max = mag[j];
- max = fac * sqrtf( (float) max );
-
- return max;
-}
-
-/*--------------------------------------------------------------------------
- * calcPartialVelocity - calculate maximum magnitude of a given partial
- * derivative
- *--------------------------------------------------------------------------
- */
-REAL
-Mapdesc::calcPartialVelocity (
- REAL *dist,
- REAL *p,
- int rstride,
- int cstride,
- int nrows,
- int ncols,
- int spartial,
- int tpartial,
- REAL srange,
- REAL trange,
- int side )
-{
- REAL tmp[MAXORDER][MAXORDER][MAXCOORDS];
- REAL mag[MAXORDER][MAXORDER];
-
- assert( nrows <= MAXORDER );
- assert( ncols <= MAXORDER );
-
- REAL *tp = &tmp[0][0][0];
- REAL *mp = &mag[0][0];
- const int istride = sizeof( tmp[0]) / sizeof( tmp[0][0][0] );
- const int jstride = sizeof( tmp[0][0]) / sizeof( tmp[0][0][0] );
- /*
- const int kstride = sizeof( tmp[0][0][0]) / sizeof( tmp[0][0][0] );
- */
- const int mistride = sizeof( mag[0]) / sizeof( mag[0][0] );
- const int mjstride = sizeof( mag[0][0]) / sizeof( mag[0][0] );
- const int idist = nrows * istride;
- const int jdist = ncols * jstride;
- /*
- const int kdist = inhcoords * kstride;
- */
- const int id = idist - spartial * istride;
- const int jd = jdist - tpartial * jstride;
-
- {
- // copy control points
- REAL *ti = tp;
- REAL *qi = p;
- REAL *til = tp + idist;
- for( ; ti != til; ) {
- REAL *tj = ti;
- REAL *qj = qi;
- REAL *tjl = ti + jdist;
- for( ; tj != tjl; ) {
- for( int k=0; k != inhcoords; k++ ) {
- tj[k] = qj[k];
- }
- tj += jstride;
- qj += cstride;
- }
- ti += istride;
- qi += rstride;
- }
- }
-
- {
- // compute (s)-partial derivative control points
- REAL *til = tp + idist - istride;
- const REAL *till = til - ( spartial * istride );
- for( ; til != till; til -= istride )
- for( REAL *ti = tp; ti != til; ti += istride )
- for( REAL *tj = ti, *tjl = tj + jdist; tj != tjl; tj += jstride )
- for( int k=0; k != inhcoords; k++ )
- tj[k] = tj[k+istride] - tj[k];
- }
-
- {
- // compute (s,t)-partial derivative control points
- REAL *tjl = tp + jdist - jstride;
- const REAL *tjll = tjl - ( tpartial * jstride );
- for( ; tjl != tjll; tjl -= jstride )
- for( REAL *tj = tp; tj != tjl; tj += jstride )
- for( REAL *ti = tj, *til = ti + id; ti != til; ti += istride )
- for( int k=0; k != inhcoords; k++ )
- ti[k] = ti[k+jstride] - ti[k];
-
- }
-
- REAL max = 0.0;
- {
- // compute magnitude and store in mag array
- memset( (void *) mp, 0, sizeof( mag ) );
- for( REAL *ti = tp, *mi = mp, *til = tp + id; ti != til; ti += istride, mi += mistride )
- for( REAL *tj = ti, *mj = mi, *tjl = ti + jd; tj != tjl; tj += jstride, mj += mjstride ) {
- for( int k=0; k != inhcoords; k++ )
- *mj += tj[k] * tj[k];
- if( *mj > max ) max = *mj;
- }
-
- }
-
- int i, j;
-
- // compute scale factor
- REAL fac = 1.0;
- {
- REAL invs = 1.0 / srange;
- REAL invt = 1.0 / trange;
- for( int s = nrows-1, slast = s-spartial; s != slast; s-- )
- fac *= s * invs;
- for( int t = ncols-1, tlast = t-tpartial; t != tlast; t-- )
- fac *= t * invt;
- }
-
- if( side == 0 ) {
- // compute max magnitude of first and last column
- dist[0] = 0.0;
- dist[1] = 0.0;
- for( i=0; i != nrows-spartial; i++ ) {
- j = 0;
- if( mag[i][j] > dist[0] ) dist[0] = mag[i][j];
-
- j = ncols-tpartial-1;
- if( mag[i][j] > dist[1] ) dist[1] = mag[i][j];
- }
- dist[0] = fac * sqrtf( dist[0] );
- dist[1] = fac * sqrtf( dist[1] );
- } else if( side == 1 ) {
- // compute max magnitude of first and last row
- dist[0] = 0.0;
- dist[1] = 0.0;
- for( j=0; j != ncols-tpartial; j++ ) {
- i = 0;
- if( mag[i][j] > dist[0] ) dist[0] = mag[i][j];
-
- i = nrows-spartial-1;
- if( mag[i][j] > dist[1] ) dist[1] = mag[i][j];
- }
- dist[0] = fac * sqrtf( dist[0] );
- dist[1] = fac * sqrtf( dist[1] );
- }
-
- max = fac * sqrtf( (float) max );
-
- return max;
-}
-
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * maplist.c++
- *
- */
-
-#include "glimports.h"
-#include "mystdio.h"
-#include "myassert.h"
-#include "mymath.h"
-#include "nurbsconsts.h"
-#include "maplist.h"
-#include "mapdesc.h"
-
-Maplist::Maplist( Backend& b )
- : mapdescPool( sizeof( Mapdesc ), 10, "mapdesc pool" ),
- backend( b )
-{
- maps = 0; lastmap = &maps;
-}
-
-void
-Maplist::initialize( void )
-{
- freeMaps();
- define( N_P2D, 0, 2 );
- define( N_P2DR, 1, 3 );
-}
-
-void
-Maplist::add( long type, int israt, int ncoords )
-{
- *lastmap = new(mapdescPool) Mapdesc( type, israt, ncoords, backend );
- lastmap = &((*lastmap)->next);
-}
-
-void
-Maplist::define( long type, int israt, int ncoords )
-{
-#ifndef NDEBUG // to avoid warning
- Mapdesc *m = locate( type );
- assert( m == NULL || ( m->isrational == israt && m->ncoords == ncoords ) );
-#endif
- add( type, israt, ncoords );
-}
-
-void
-Maplist::remove( Mapdesc *m )
-{
- for( Mapdesc **curmap = &maps; *curmap; curmap = &((*curmap)->next) ) {
- if( *curmap == m ) {
- *curmap = m->next;
- m->deleteMe( mapdescPool );
- return;
- }
- }
- abort();
-}
-
-void
-Maplist::freeMaps( void )
-{
- mapdescPool.clear();
- maps = 0;
- lastmap = &maps;
-}
-
-Mapdesc *
-Maplist::find( long type )
-{
- Mapdesc *val = locate( type );
- assert( val != 0 );
- return val;
-}
-
-Mapdesc *
-Maplist::locate( long type )
-{
- Mapdesc *m;
- for( m = maps; m; m = m->next )
- if( m->getType() == type ) break;
- return m;
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * maplist.h
- *
- */
-
-#ifndef __glumaplist_h_
-#define __glumaplist_h_
-
-#include "types.h"
-#include "defines.h"
-#include "bufpool.h"
-
-class Backend;
-class Mapdesc;
-
-class Maplist {
-public:
- Maplist( Backend & );
- void define( long, int, int );
- inline void undefine( long );
- inline int isMap( long );
-
- void initialize( void );
- Mapdesc * find( long );
- Mapdesc * locate( long );
-
-private:
- Pool mapdescPool;
- Mapdesc * maps;
- Mapdesc ** lastmap;
- Backend & backend;
-
- void add( long, int, int );
- void remove( Mapdesc * );
- void freeMaps( void );
-};
-
-inline int
-Maplist::isMap( long type )
-{
- return (locate( type ) ? 1 : 0);
-}
-
-inline void
-Maplist::undefine( long type )
-{
- Mapdesc *m = locate( type );
- assert( m != 0 );
- remove( m );
-}
-#endif /* __glumaplist_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * mesher.c++
- *
- */
-
-#include "glimports.h"
-#include "myassert.h"
-#include "mystdio.h"
-#include "gridvertex.h"
-#include "gridtrimvertex.h"
-#include "jarcloc.h"
-#include "gridline.h"
-#include "trimline.h"
-#include "uarray.h"
-#include "backend.h"
-#include "mesher.h"
-
-
-const float Mesher::ZERO = 0.0;
-
-Mesher::Mesher( Backend& b )
- : backend( b ),
- p( sizeof( GridTrimVertex ), 100, "GridTrimVertexPool" )
-{
- stacksize = 0;
- vdata = 0;
- last[0] = 0;
- last[1] = 0;
- itop = 0;
- lastedge = 0; //needed to prevent purify UMR
-}
-
-Mesher::~Mesher( void )
-{
- if( vdata ) delete[] vdata;
-}
-
-void
-Mesher::init( unsigned int npts )
-{
- p.clear();
- if( stacksize < npts ) {
- stacksize = 2 * npts;
- if( vdata ) delete[] vdata;
- vdata = new GridTrimVertex_p[stacksize];
- }
-}
-
-inline void
-Mesher::push( GridTrimVertex *gt )
-{
- assert( itop+1 != (int)stacksize );
- vdata[++itop] = gt;
-}
-
-inline void
-Mesher::pop( long )
-{
-}
-
-inline void
-Mesher::openMesh()
-{
- backend.bgntmesh( "addedge" );
-}
-
-inline void
-Mesher::closeMesh()
-{
- backend.endtmesh();
-}
-
-inline void
-Mesher::swapMesh()
-{
- backend.swaptmesh();
-}
-
-inline void
-Mesher::clearStack()
-{
- itop = -1;
- last[0] = 0;
-}
-
-void
-Mesher::finishLower( GridTrimVertex *gtlower )
-{
- for( push(gtlower);
- nextlower( gtlower=new(p) GridTrimVertex );
- push(gtlower) )
- addLower();
- addLast();
-}
-
-void
-Mesher::finishUpper( GridTrimVertex *gtupper )
-{
- for( push(gtupper);
- nextupper( gtupper=new(p) GridTrimVertex );
- push(gtupper) )
- addUpper();
- addLast();
-}
-
-void
-Mesher::mesh( void )
-{
- GridTrimVertex *gtlower, *gtupper;
-
- Hull::init( );
- nextupper( gtupper = new(p) GridTrimVertex );
- nextlower( gtlower = new(p) GridTrimVertex );
-
- clearStack();
- openMesh();
- push(gtupper);
-
- nextupper( gtupper = new(p) GridTrimVertex );
- nextlower( gtlower );
-
- assert( gtupper->t && gtlower->t );
-
- if( gtupper->t->param[0] < gtlower->t->param[0] ) {
- push(gtupper);
- lastedge = 1;
- if( nextupper( gtupper=new(p) GridTrimVertex ) == 0 ) {
- finishLower(gtlower);
- return;
- }
- } else if( gtupper->t->param[0] > gtlower->t->param[0] ) {
- push(gtlower);
- lastedge = 0;
- if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) {
- finishUpper(gtupper);
- return;
- }
- } else {
- if( lastedge == 0 ) {
- push(gtupper);
- lastedge = 1;
- if( nextupper(gtupper=new(p) GridTrimVertex) == 0 ) {
- finishLower(gtlower);
- return;
- }
- } else {
- push(gtlower);
- lastedge = 0;
- if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) {
- finishUpper(gtupper);
- return;
- }
- }
- }
-
- while ( 1 ) {
- if( gtupper->t->param[0] < gtlower->t->param[0] ) {
- push(gtupper);
- addUpper();
- if( nextupper( gtupper=new(p) GridTrimVertex ) == 0 ) {
- finishLower(gtlower);
- return;
- }
- } else if( gtupper->t->param[0] > gtlower->t->param[0] ) {
- push(gtlower);
- addLower();
- if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) {
- finishUpper(gtupper);
- return;
- }
- } else {
- if( lastedge == 0 ) {
- push(gtupper);
- addUpper();
- if( nextupper( gtupper=new(p) GridTrimVertex ) == 0 ) {
- finishLower(gtlower);
- return;
- }
- } else {
- push(gtlower);
- addLower();
- if( nextlower( gtlower=new(p) GridTrimVertex ) == 0 ) {
- finishUpper(gtupper);
- return;
- }
- }
- }
- }
-}
-
-inline int
-Mesher::isCcw( int ilast )
-{
- REAL area = det3( vdata[ilast]->t, vdata[itop-1]->t, vdata[itop-2]->t );
- return (area < ZERO) ? 0 : 1;
-}
-
-inline int
-Mesher::isCw( int ilast )
-{
- REAL area = det3( vdata[ilast]->t, vdata[itop-1]->t, vdata[itop-2]->t );
- return (area > -ZERO) ? 0 : 1;
-}
-
-inline int
-Mesher::equal( int x, int y )
-{
- return( last[0] == vdata[x] && last[1] == vdata[y] );
-}
-
-inline void
-Mesher::copy( int x, int y )
-{
- last[0] = vdata[x]; last[1] = vdata[y];
-}
-
-inline void
-Mesher::move( int x, int y )
-{
- vdata[x] = vdata[y];
-}
-
-inline void
-Mesher::output( int x )
-{
- backend.tmeshvert( vdata[x] );
-}
-
-/*---------------------------------------------------------------------------
- * addedge - addedge an edge to the triangulation
- *
- * This code has been re-written to generate large triangle meshes
- * from a monotone polygon. Although smaller triangle meshes
- * could be generated faster and with less code, larger meshes
- * actually give better SYSTEM performance. This is because
- * vertices are processed in the backend slower than they are
- * generated by this code and any decrease in the number of vertices
- * results in a decrease in the time spent in the backend.
- *---------------------------------------------------------------------------
- */
-
-void
-Mesher::addLast( )
-{
- register int ilast = itop;
-
- if( lastedge == 0 ) {
- if( equal( 0, 1 ) ) {
- output( ilast );
- swapMesh();
- for( register int i = 2; i < ilast; i++ ) {
- swapMesh();
- output( i );
- }
- copy( ilast, ilast-1 );
- } else if( equal( ilast-2, ilast-1) ) {
- swapMesh();
- output( ilast );
- for( register int i = ilast-3; i >= 0; i-- ) {
- output( i );
- swapMesh();
- }
- copy( 0, ilast );
- } else {
- closeMesh(); openMesh();
- output( ilast );
- output( 0 );
- for( register int i = 1; i < ilast; i++ ) {
- swapMesh();
- output( i );
- }
- copy( ilast, ilast-1 );
- }
- } else {
- if( equal( 1, 0) ) {
- swapMesh();
- output( ilast );
- for( register int i = 2; i < ilast; i++ ) {
- output( i );
- swapMesh();
- }
- copy( ilast-1, ilast );
- } else if( equal( ilast-1, ilast-2) ) {
- output( ilast );
- swapMesh();
- for( register int i = ilast-3; i >= 0; i-- ) {
- swapMesh();
- output( i );
- }
- copy( ilast, 0 );
- } else {
- closeMesh(); openMesh();
- output( 0 );
- output( ilast );
- for( register int i = 1; i < ilast; i++ ) {
- output( i );
- swapMesh();
- }
- copy( ilast-1, ilast );
- }
- }
- closeMesh();
- //for( register long k=0; k<=ilast; k++ ) pop( k );
-}
-
-void
-Mesher::addUpper( )
-{
- register int ilast = itop;
-
- if( lastedge == 0 ) {
- if( equal( 0, 1 ) ) {
- output( ilast );
- swapMesh();
- for( register int i = 2; i < ilast; i++ ) {
- swapMesh();
- output( i );
- }
- copy( ilast, ilast-1 );
- } else if( equal( ilast-2, ilast-1) ) {
- swapMesh();
- output( ilast );
- for( register int i = ilast-3; i >= 0; i-- ) {
- output( i );
- swapMesh();
- }
- copy( 0, ilast );
- } else {
- closeMesh(); openMesh();
- output( ilast );
- output( 0 );
- for( register int i = 1; i < ilast; i++ ) {
- swapMesh();
- output( i );
- }
- copy( ilast, ilast-1 );
- }
- lastedge = 1;
- //for( register long k=0; k<ilast-1; k++ ) pop( k );
- move( 0, ilast-1 );
- move( 1, ilast );
- itop = 1;
- } else {
- if( ! isCcw( ilast ) ) return;
- do {
- itop--;
- } while( (itop > 1) && isCcw( ilast ) );
-
- if( equal( ilast-1, ilast-2 ) ) {
- output( ilast );
- swapMesh();
- for( register int i=ilast-3; i>=itop-1; i-- ) {
- swapMesh();
- output( i );
- }
- copy( ilast, itop-1 );
- } else if( equal( itop, itop-1 ) ) {
- swapMesh();
- output( ilast );
- for( register int i = itop+1; i < ilast; i++ ) {
- output( i );
- swapMesh();
- }
- copy( ilast-1, ilast );
- } else {
- closeMesh(); openMesh();
- output( ilast );
- output( ilast-1 );
- for( register int i=ilast-2; i>=itop-1; i-- ) {
- swapMesh();
- output( i );
- }
- copy( ilast, itop-1 );
- }
- //for( register int k=itop; k<ilast; k++ ) pop( k );
- move( itop, ilast );
- }
-}
-
-void
-Mesher::addLower()
-{
- register int ilast = itop;
-
- if( lastedge == 1 ) {
- if( equal( 1, 0) ) {
- swapMesh();
- output( ilast );
- for( register int i = 2; i < ilast; i++ ) {
- output( i );
- swapMesh();
- }
- copy( ilast-1, ilast );
- } else if( equal( ilast-1, ilast-2) ) {
- output( ilast );
- swapMesh();
- for( register int i = ilast-3; i >= 0; i-- ) {
- swapMesh();
- output( i );
- }
- copy( ilast, 0 );
- } else {
- closeMesh(); openMesh();
- output( 0 );
- output( ilast );
- for( register int i = 1; i < ilast; i++ ) {
- output( i );
- swapMesh();
- }
- copy( ilast-1, ilast );
- }
-
- lastedge = 0;
- //for( register long k=0; k<ilast-1; k++ ) pop( k );
- move( 0, ilast-1 );
- move( 1, ilast );
- itop = 1;
- } else {
- if( ! isCw( ilast ) ) return;
- do {
- itop--;
- } while( (itop > 1) && isCw( ilast ) );
-
- if( equal( ilast-2, ilast-1) ) {
- swapMesh();
- output( ilast );
- for( register int i=ilast-3; i>=itop-1; i--) {
- output( i );
- swapMesh( );
- }
- copy( itop-1, ilast );
- } else if( equal( itop-1, itop) ) {
- output( ilast );
- swapMesh();
- for( register int i=itop+1; i<ilast; i++ ) {
- swapMesh( );
- output( i );
- }
- copy( ilast, ilast-1 );
- } else {
- closeMesh(); openMesh();
- output( ilast-1 );
- output( ilast );
- for( register int i=ilast-2; i>=itop-1; i-- ) {
- output( i );
- swapMesh( );
- }
- copy( itop-1, ilast );
- }
- //for( register int k=itop; k<ilast; k++ ) pop( k );
- move( itop, ilast );
- }
-}
-
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * mesher.h
- *
- */
-
-#ifndef __glumesher_h_
-#define __glumesher_h_
-
-#include "hull.h"
-
-class TrimRegion;
-class Backend;
-class Pool;
-// struct GridTrimVertex;
-
-
-class Mesher : virtual public TrimRegion, public Hull {
-public:
- Mesher( Backend & );
- ~Mesher( void );
- void init( unsigned int );
- void mesh( void );
-
-private:
- static const float ZERO;
- Backend& backend;
-
- Pool p;
- unsigned int stacksize;
- GridTrimVertex ** vdata;
- GridTrimVertex * last[2];
- int itop;
- int lastedge;
-
- inline void openMesh( void );
- inline void swapMesh( void );
- inline void closeMesh( void );
- inline int isCcw( int );
- inline int isCw( int );
- inline void clearStack( void );
- inline void push( GridTrimVertex * );
- inline void pop( long );
- inline void move( int, int );
- inline int equal( int, int );
- inline void copy( int, int );
- inline void output( int );
- void addUpper( void );
- void addLower( void );
- void addLast( void );
- void finishUpper( GridTrimVertex * );
- void finishLower( GridTrimVertex * );
-};
-#endif /* __glumesher_h_ */
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include "monoTriangulation.h"
-#include "polyUtil.h"
-#include "backend.h"
-#include "arc.h"
-
-void reflexChain::outputFan(Real v[2], Backend* backend)
-{
- Int i;
- /*
- TrimVertex trimVert;
- */
- backend->bgntfan();
-
- /*
- trimVert.param[0]=v[0];
- trimVert.param[1]=v[1];
- backend->tmeshvert(&trimVert);
- */
- backend->tmeshvert(v[0], v[1]);
-
- if(isIncreasing) {
- for(i=0; i<index_queue; i++)
- {
- /*
- trimVert.param[0]=queue[i][0];
- trimVert.param[1]=queue[i][1];
- backend->tmeshvert(&trimVert);
- */
- backend->tmeshvert(queue[i][0], queue[i][1]);
- }
- }
- else {
- for(i=index_queue-1; i>=0; i--)
- {
- /*
- trimVert.param[0]=queue[i][0];
- trimVert.param[1]=queue[i][1];
- backend->tmeshvert(&trimVert);
- */
- backend->tmeshvert(queue[i][0], queue[i][1]);
- }
- }
- backend->endtfan();
-}
-
-void reflexChain::processNewVertex(Real v[2], Backend* backend)
-{
- Int i,j,k;
- Int isReflex;
- /*TrimVertex trimVert;*/
- /*if there are at most one vertex in the queue, then simply insert
- */
- if(index_queue <=1){
- insert(v);
- return;
- }
-
- /*there are at least two vertices in the queue*/
- j=index_queue-1;
-
- for(i=j; i>=1; i--) {
- if(isIncreasing) {
- isReflex = (area(queue[i-1], queue[i], v) <= 0.0);
- }
- else /*decreasing*/{
- isReflex = (area(v, queue[i], queue[i-1]) <= 0.0);
- }
- if(isReflex) {
- break;
- }
- }
-
- /*
- *if i<j then vertices: i+1--j are convex
- * output triangle fan:
- * v, and queue[i], i+1, ..., j
- */
- if(i<j)
- {
- backend->bgntfan();
- /*
- trimVert.param[0]=v[0];
- trimVert.param[1]=v[1];
- backend->tmeshvert(& trimVert);
- */
- backend->tmeshvert(v[0], v[1]);
-
- if(isIncreasing) {
- for(k=i; k<=j; k++)
- {
- /*
- trimVert.param[0]=queue[k][0];
- trimVert.param[1]=queue[k][1];
- backend->tmeshvert(& trimVert);
- */
- backend->tmeshvert(queue[k][0], queue[k][1]);
- }
- }
- else {
- for(k=j; k>=i; k--)
- {
- /*
- trimVert.param[0]=queue[k][0];
- trimVert.param[1]=queue[k][1];
- backend->tmeshvert(& trimVert);
- */
- backend->tmeshvert(queue[k][0], queue[k][1]);
- }
- }
-
- backend->endtfan();
- }
-
- /*delete vertices i+1--j from the queue*/
- index_queue = i+1;
- /*finally insert v at the end of the queue*/
- insert(v);
-
-}
-
-
-void monoTriangulationRec(Real* topVertex, Real* botVertex,
- vertexArray* inc_chain, Int inc_current,
- vertexArray* dec_chain, Int dec_current,
- Backend* backend)
-{
- assert( inc_chain != NULL && dec_chain != NULL);
- assert( ! (inc_current>=inc_chain->getNumElements() &&
- dec_current>=dec_chain->getNumElements()));
- Int inc_nVertices;
- Int dec_nVertices;
- Real** inc_array ;
- Real** dec_array ;
- Int i;
- assert( ! ( (inc_chain==NULL) && (dec_chain==NULL)));
-
- if(inc_current>=inc_chain->getNumElements()) /*no more vertices on inc_chain*/
- {
-
- dec_array = dec_chain->getArray();
- dec_nVertices = dec_chain->getNumElements();
- reflexChain rChain(20,0);
- /*put the top vertex into the reflex chain*/
- rChain.processNewVertex(topVertex, backend);
- /*process all the vertices on the dec_chain*/
- for(i=dec_current; i<dec_nVertices; i++){
- rChain.processNewVertex(dec_array[i], backend);
- }
- /*process the bottom vertex*/
- rChain.processNewVertex(botVertex, backend);
-
- }
- else if(dec_current>= dec_chain->getNumElements()) /*no more vertices on dec_chain*/
- {
- inc_array = inc_chain->getArray();
- inc_nVertices= inc_chain->getNumElements();
- reflexChain rChain(20,1);
- /*put the top vertex into the reflex chain*/
- rChain.processNewVertex(topVertex, backend);
- /*process all the vertices on the inc_chain*/
- for(i=inc_current; i<inc_nVertices; i++){
- rChain.processNewVertex(inc_array[i], backend);
- }
- /*process the bottom vertex*/
- rChain.processNewVertex(botVertex, backend);
- }
- else /*neither chain is empty*/
- {
- inc_array = inc_chain -> getArray();
- dec_array = dec_chain -> getArray();
- inc_nVertices= inc_chain->getNumElements();
- dec_nVertices= dec_chain->getNumElements();
- /*if top of inc_chain is 'lower' than top of dec_chain, process all the
- *vertices on the dec_chain which are higher than top of inc_chain
- */
- if(compV2InY(inc_array[inc_current], dec_array[dec_current]) <= 0)
- {
-
- reflexChain rChain(20, 0);
- rChain.processNewVertex(topVertex, backend);
- for(i=dec_current; i<dec_nVertices; i++)
- {
- if(compV2InY(inc_array[inc_current], dec_array[i]) <= 0)
- rChain.processNewVertex(dec_array[i], backend);
- else
- break;
- }
- rChain.outputFan(inc_array[inc_current], backend);
- monoTriangulationRec(dec_array[i-1], botVertex,
- inc_chain, inc_current,
- dec_chain, i,
- backend);
- }
- else /*compV2InY(inc_array[inc_current], dec_array[dec_current]) > 0*/
- {
-
- reflexChain rChain(20, 1);
- rChain.processNewVertex(topVertex, backend);
- for(i=inc_current; i<inc_nVertices; i++)
- {
- if(compV2InY(inc_array[i], dec_array[dec_current]) >0)
- rChain.processNewVertex(inc_array[i], backend);
- else
- break;
- }
- rChain.outputFan(dec_array[dec_current], backend);
- monoTriangulationRec(inc_array[i-1], botVertex,
- inc_chain, i,
- dec_chain, dec_current,
- backend);
- }
- }/*end case neither is empty*/
-}
-
-
-void monoTriangulationFunBackend(Arc_ptr loop, Int (*compFun)(Real*, Real*), Backend* backend)
-{
- Int i;
- /*find the top vertex, bottom vertex, inccreasing chain, and decreasing chain,
- *then call monoTriangulationRec
- */
- Arc_ptr tempV;
- Arc_ptr topV;
- Arc_ptr botV;
- topV = botV = loop;
- for(tempV = loop->next; tempV != loop; tempV = tempV->next)
- {
- if(compFun(topV->tail(), tempV->tail())<0) {
- topV = tempV;
- }
- if(compFun(botV->tail(), tempV->tail())>0) {
- botV = tempV;
- }
- }
-
- /*creat increase and decrease chains*/
- vertexArray inc_chain(20); /*this is a dynamic array*/
- for(i=1; i<=topV->pwlArc->npts-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/
- inc_chain.appendVertex(topV->pwlArc->pts[i].param);
- }
- for(tempV = topV->next; tempV != botV; tempV = tempV->next)
- {
- for(i=0; i<=tempV->pwlArc->npts-2; i++){
- inc_chain.appendVertex(tempV->pwlArc->pts[i].param);
- }
- }
-
- vertexArray dec_chain(20);
- for(tempV = topV->prev; tempV != botV; tempV = tempV->prev)
- {
- for(i=tempV->pwlArc->npts-2; i>=0; i--){
- dec_chain.appendVertex(tempV->pwlArc->pts[i].param);
- }
- }
- for(i=botV->pwlArc->npts-2; i>=1; i--){
- dec_chain.appendVertex(tempV->pwlArc->pts[i].param);
- }
-
- monoTriangulationRecFunBackend(topV->tail(), botV->tail(), &inc_chain, 0, &dec_chain, 0, compFun, backend);
-
-}
-
-/*if compFun == compV2InY, top to bottom: V-monotone
- *if compFun == compV2InX, right to left: U-monotone
- */
-void monoTriangulationRecFunBackend(Real* topVertex, Real* botVertex,
- vertexArray* inc_chain, Int inc_current,
- vertexArray* dec_chain, Int dec_current,
- Int (*compFun)(Real*, Real*),
- Backend* backend)
-{
- assert( inc_chain != NULL && dec_chain != NULL);
- assert( ! (inc_current>=inc_chain->getNumElements() &&
- dec_current>=dec_chain->getNumElements()));
- Int inc_nVertices;
- Int dec_nVertices;
- Real** inc_array ;
- Real** dec_array ;
- Int i;
- assert( ! ( (inc_chain==NULL) && (dec_chain==NULL)));
-
- if(inc_current>=inc_chain->getNumElements()) /*no more vertices on inc_chain*/
- {
-
- dec_array = dec_chain->getArray();
- dec_nVertices = dec_chain->getNumElements();
- reflexChain rChain(20,0);
- /*put the top vertex into the reflex chain*/
- rChain.processNewVertex(topVertex, backend);
- /*process all the vertices on the dec_chain*/
- for(i=dec_current; i<dec_nVertices; i++){
- rChain.processNewVertex(dec_array[i], backend);
- }
- /*process the bottom vertex*/
- rChain.processNewVertex(botVertex, backend);
-
- }
- else if(dec_current>= dec_chain->getNumElements()) /*no more vertices on dec_chain*/
- {
- inc_array = inc_chain->getArray();
- inc_nVertices= inc_chain->getNumElements();
- reflexChain rChain(20,1);
- /*put the top vertex into the reflex chain*/
- rChain.processNewVertex(topVertex, backend);
- /*process all the vertices on the inc_chain*/
- for(i=inc_current; i<inc_nVertices; i++){
- rChain.processNewVertex(inc_array[i], backend);
- }
- /*process the bottom vertex*/
- rChain.processNewVertex(botVertex, backend);
- }
- else /*neither chain is empty*/
- {
- inc_array = inc_chain -> getArray();
- dec_array = dec_chain -> getArray();
- inc_nVertices= inc_chain->getNumElements();
- dec_nVertices= dec_chain->getNumElements();
- /*if top of inc_chain is 'lower' than top of dec_chain, process all the
- *vertices on the dec_chain which are higher than top of inc_chain
- */
- if(compFun(inc_array[inc_current], dec_array[dec_current]) <= 0)
- {
-
- reflexChain rChain(20, 0);
- rChain.processNewVertex(topVertex, backend);
- for(i=dec_current; i<dec_nVertices; i++)
- {
- if(compFun(inc_array[inc_current], dec_array[i]) <= 0)
- rChain.processNewVertex(dec_array[i], backend);
- else
- break;
- }
- rChain.outputFan(inc_array[inc_current], backend);
- monoTriangulationRecFunBackend(dec_array[i-1], botVertex,
- inc_chain, inc_current,
- dec_chain, i,
- compFun,
- backend);
- }
- else /*compFun(inc_array[inc_current], dec_array[dec_current]) > 0*/
- {
-
- reflexChain rChain(20, 1);
- rChain.processNewVertex(topVertex, backend);
- for(i=inc_current; i<inc_nVertices; i++)
- {
- if(compFun(inc_array[i], dec_array[dec_current]) >0)
- rChain.processNewVertex(inc_array[i], backend);
- else
- break;
- }
- rChain.outputFan(dec_array[dec_current], backend);
- monoTriangulationRecFunBackend(inc_array[i-1], botVertex,
- inc_chain, i,
- dec_chain, dec_current,
- compFun,
- backend);
- }
- }/*end case neither is empty*/
-}
+++ /dev/null
-/*
-** 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++
- *
- */
-
-#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;
-}
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * monotonizer.h
- *
- */
-
-#ifndef __glumonotonizer_h_
-#define __glumonotonizer_h_
-
-#include "mysetjmp.h"
-#include "types.h"
-
-class Arc;
-class ArcTessellator;
-class Pool;
-class Bin;
-class PwlArcPool;
-class Mapdesc;
-
-class Monotonizer {
- ArcTessellator& arctessellator;
- Pool& arcpool;
- Pool& pwlarcpool;
- jmp_buf& nurbsJmpBuf;
-
- enum dir { down, same, up, none };
- void tessellate( Arc *, REAL );
- void monotonize( Arc *, Bin & );
- int isMonotone( Arc * );
-public:
- Monotonizer( ArcTessellator& at, Pool& ap, Pool& p, jmp_buf& j )
- : arctessellator(at), arcpool(ap), pwlarcpool(p), nurbsJmpBuf(j) {}
- int decompose( Bin &, REAL );
-};
-#endif /* __glumonotonizer_h_ */
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * myassert.h
- *
- */
-
-#ifndef __glumyassert_h_
-#define __glumyassert_h_
-
-#ifdef STANDALONE
-#define assert(EX) ((void)0)
-#endif
-
-#ifdef LIBRARYBUILD
-#include <assert.h>
-#endif
-
-#ifdef GLBUILD
-#define assert(EX) ((void)0)
-#endif
-
-#endif /* __glumyassert_h_ */
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include "mymath.h"
-
-#ifdef NEEDCEILF
-
-float ceilf( float x )
-{
- if( x < 0 ) {
- float nx = -x;
- int ix = (int) nx;
- return (float) -ix;
- } else {
- int ix = (int) x;
- if( x == (float) ix ) return x;
- return (float) (ix+1);
- }
-}
-
-float floorf( float x )
-{
- if( x < 0 ) {
- float nx = -x;
- int ix = (int) nx;
- if( nx == (float) ix ) return x;
- return (float) -(ix+1);
- } else {
- int ix = (int) x;
- return (float) ix;
- }
-}
-#endif
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * mymath.h
- *
- */
-
-#ifndef __glumymath_h_
-#define __glumymath_h_
-
-#ifdef GLBUILD
-#define sqrtf gl_fsqrt
-#endif
-
-#if defined(GLBUILD) || defined(STANDALONE)
-#define M_SQRT2 1.41421356237309504880
-#define ceilf myceilf
-#define floorf myfloorf
-#define sqrtf sqrt
-extern "C" double sqrt(double);
-extern "C" float ceilf(float);
-extern "C" float floorf(float);
-#define NEEDCEILF
-#endif
-
-#ifdef LIBRARYBUILD
-#include <math.h>
-#endif
-
-#if !defined sqrtf
-# define sqrtf(x) ((float)sqrt(x))
-#endif
-#if !defined ceilf
-# define ceilf(x) ((float)ceil(x))
-#endif
-#if !defined floorf
-# define floorf(x) ((float)floor(x))
-#endif
-
-#endif /* __glumymath_h_ */
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * mysetjmp.h
- *
- */
-
-#ifndef __glumysetjmp_h_
-#define __glumysetjmp_h_
-
-#ifdef STANDALONE
-struct JumpBuffer;
-extern "C" JumpBuffer *newJumpbuffer( void );
-extern "C" void deleteJumpbuffer(JumpBuffer *);
-extern "C" void mylongjmp( JumpBuffer *, int );
-extern "C" int mysetjmp( JumpBuffer * );
-#endif
-
-#ifdef GLBUILD
-#define setjmp gl_setjmp
-#define longjmp gl_longjmp
-#endif
-
-#if defined(LIBRARYBUILD) || defined(GLBUILD)
-#include <setjmp.h>
-#include <stdlib.h>
-
-struct JumpBuffer {
- jmp_buf buf;
-};
-
-inline JumpBuffer *
-newJumpbuffer( void )
-{
- return (JumpBuffer *) malloc( sizeof( JumpBuffer ) );
-}
-
-inline void
-deleteJumpbuffer(JumpBuffer *jb)
-{
- free( (void *) jb);
-}
-
-inline void
-mylongjmp( JumpBuffer *j, int code )
-{
- ::longjmp( j->buf, code );
-}
-
-inline int
-mysetjmp( JumpBuffer *j )
-{
- return setjmp( j->buf );
-}
-#endif
-
-#endif /* __glumysetjmp_h_ */
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * mystring.h
- *
- */
-
-#ifndef __glumystring_h_
-#define __glumystring_h_
-
-#ifdef STANDALONE
-typedef unsigned int size_t;
-extern "C" void * memcpy(void *, const void *, size_t);
-extern "C" void * memset(void *, int, size_t);
-#endif
-
-#ifdef GLBUILD
-#define memcpy(a,b,c) bcopy(b,a,c)
-#define memset(a,b,c) bzero(a,c)
-extern "C" void bcopy(const void *, void *, int);
-extern "C" void bzero(void *, int);
-#endif
-
-#ifdef LIBRARYBUILD
-#include <string.h>
-#endif
-
-#endif /* __glumystring_h_ */
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * nurbsconsts.h
- *
- */
-
-#ifndef __glunurbsconsts_h_
-#define __glunurbsconsts_h_
-
-/* NURBS Properties - one set per map,
- each takes a single INREAL arg */
-#define N_SAMPLING_TOLERANCE 1
-#define N_S_RATE 6
-#define N_T_RATE 7
-#define N_CLAMPFACTOR 13
-#define N_NOCLAMPING 0.0
-#define N_MINSAVINGS 14
-#define N_NOSAVINGSSUBDIVISION 0.0
-
-/* NURBS Properties - one set per map,
- each takes an enumerated value */
-#define N_CULLING 2
-#define N_NOCULLING 0.0
-#define N_CULLINGON 1.0
-#define N_SAMPLINGMETHOD 10
-#define N_NOSAMPLING 0.0
-#define N_FIXEDRATE 3.0
-#define N_DOMAINDISTANCE 2.0
-#define N_PARAMETRICDISTANCE 5.0
-#define N_PATHLENGTH 6.0
-#define N_SURFACEAREA 7.0
-#define N_OBJECTSPACE_PARA 8.0
-#define N_OBJECTSPACE_PATH 9.0
-#define N_BBOX_SUBDIVIDING 17
-#define N_NOBBOXSUBDIVISION 0.0
-#define N_BBOXTIGHT 1.0
-#define N_BBOXROUND 2.0
-
-/* NURBS Rendering Properties - one set per renderer
- each takes an enumerated value */
-#define N_DISPLAY 3
-#define N_FILL 1.0
-#define N_OUTLINE_POLY 2.0
-#define N_OUTLINE_TRI 3.0
-#define N_OUTLINE_QUAD 4.0
-#define N_OUTLINE_PATCH 5.0
-#define N_OUTLINE_PARAM 6.0
-#define N_OUTLINE_PARAM_S 7.0
-#define N_OUTLINE_PARAM_ST 8.0
-#define N_OUTLINE_SUBDIV 9.0
-#define N_OUTLINE_SUBDIV_S 10.0
-#define N_OUTLINE_SUBDIV_ST 11.0
-#define N_ISOLINE_S 12.0
-#define N_ERRORCHECKING 4
-#define N_NOMSG 0.0
-#define N_MSG 1.0
-
-/* GL 4.0 propeties not defined above */
-#ifndef N_PIXEL_TOLERANCE
-#define N_PIXEL_TOLERANCE N_SAMPLING_TOLERANCE
-#define N_ERROR_TOLERANCE 20
-#define N_SUBDIVISIONS 5
-#define N_TILES 8
-#define N_TMP1 9
-#define N_TMP2 N_SAMPLINGMETHOD
-#define N_TMP3 11
-#define N_TMP4 12
-#define N_TMP5 N_CLAMPFACTOR
-#define N_TMP6 N_MINSAVINGS
-#define N_S_STEPS N_S_RATE
-#define N_T_STEPS N_T_RATE
-#endif
-
-/* NURBS Rendering Properties - one set per map,
- each takes an INREAL matrix argument */
-#define N_CULLINGMATRIX 1
-#define N_SAMPLINGMATRIX 2
-#define N_BBOXMATRIX 3
-
-
-/* NURBS Rendering Properties - one set per map,
- each takes an INREAL vector argument */
-#define N_BBOXSIZE 4
-
-/* type argument for trimming curves */
-#ifndef N_P2D
-#define N_P2D 0x8
-#define N_P2DR 0xd
-#endif
-
-#endif /* __glunurbsconsts_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * nurbsinterfac.c++
- *
- */
-
-#include "glimports.h"
-#include "mystdio.h"
-#include "nurbsconsts.h"
-#include "nurbstess.h"
-#include "bufpool.h"
-#include "quilt.h"
-#include "displaylist.h"
-#include "knotvector.h"
-#include "mapdesc.h"
-
-#define THREAD( work, arg, cleanup ) \
- if( dl ) {\
- arg->save = 1;\
- dl->append( (PFVS)&NurbsTessellator::work, (void *) arg, (PFVS)&NurbsTessellator::cleanup );\
- } else {\
- arg->save = 0;\
- work( arg );\
- }
-
-#define THREAD2( work ) \
- if( dl ) {\
- dl->append( (PFVS)&NurbsTessellator::work, 0, 0 );\
- } else {\
- work( );\
- }
-
-NurbsTessellator::NurbsTessellator( BasicCurveEvaluator &c, BasicSurfaceEvaluator& e)
- : maplist( backend ),
- backend( c, e ),
- subdivider( renderhints, backend ),
- o_pwlcurvePool( sizeof( O_pwlcurve ), 32, "o_pwlcurvePool" ),
- o_nurbscurvePool( sizeof( O_nurbscurve ), 32, "o_nurbscurvePool"),
- o_curvePool( sizeof( O_curve ), 32, "o_curvePool" ),
- o_trimPool( sizeof( O_trim ), 32, "o_trimPool" ),
- o_surfacePool( sizeof( O_surface ), 1, "o_surfacePool" ),
- o_nurbssurfacePool( sizeof( O_nurbssurface ), 4, "o_nurbssurfacePool" ),
- propertyPool( sizeof( Property ), 32, "propertyPool" ),
- quiltPool( sizeof( Quilt ), 32, "quiltPool" )
-{
- dl = 0;
- inSurface = 0;
- inCurve = 0;
- inTrim = 0;
- playBack = 0;
- jumpbuffer = newJumpbuffer();
- subdivider.setJumpbuffer( jumpbuffer );
-}
-
-NurbsTessellator::~NurbsTessellator( void )
-{
- if( inTrim ) {
- do_nurbserror( 12 );
- endtrim();
- }
-
- if( inSurface ) {
- *nextNurbssurface = 0;
- do_freeall();
- }
-
- if (jumpbuffer) {
- deleteJumpbuffer(jumpbuffer);
- jumpbuffer= 0;
- }
-}
-
-/*-----------------------------------------------------------------------------
- * bgnsurface - allocate and initialize an o_surface structure
- *
- * Client: GL user
- *-----------------------------------------------------------------------------
- */
-void
-NurbsTessellator::bgnsurface( long nuid )
-{
- O_surface *o_surface = new(o_surfacePool) O_surface;
- o_surface->nuid = nuid;
- THREAD( do_bgnsurface, o_surface, do_freebgnsurface );
-}
-
-/*-----------------------------------------------------------------------------
- * bgncurve - allocate an initialize an o_curve structure
- *
- * Client: GL user
- *-----------------------------------------------------------------------------
- */
-void
-NurbsTessellator::bgncurve( long nuid )
-{
- O_curve *o_curve = new(o_curvePool) O_curve;
- o_curve->nuid = nuid;
- THREAD( do_bgncurve, o_curve, do_freebgncurve );
-}
-/*-----------------------------------------------------------------------------
- * endcurve -
- *
- * Client:
- *-----------------------------------------------------------------------------
- */
-
-void
-NurbsTessellator::endcurve( void )
-{
- THREAD2( do_endcurve );
-}
-
-/*-----------------------------------------------------------------------------
- * endsurface - user level end of surface call
- *
- * Client: GL user
- *-----------------------------------------------------------------------------
- */
-void
-NurbsTessellator::endsurface( void )
-{
- THREAD2( do_endsurface );
-}
-
-
-/*-----------------------------------------------------------------------------
- * bgntrim - allocate and initialize a new trim loop structure (o_trim )
- *
- * Client: GL user
- *-----------------------------------------------------------------------------
- */
-void
-NurbsTessellator::bgntrim( void )
-{
- O_trim *o_trim = new(o_trimPool) O_trim;
- THREAD( do_bgntrim, o_trim, do_freebgntrim );
-}
-
-/*-----------------------------------------------------------------------------
- * endtrim -
- *
- * Client: GL user
- *-----------------------------------------------------------------------------
- */
-void
-NurbsTessellator::endtrim( void )
-{
- THREAD2( do_endtrim );
-}
-
-
-/*-----------------------------------------------------------------------------
- * pwlcurve -
- *
- * count - number of points on curve
- * array - array of points on curve
- * byte_stride - distance between points in bytes
- * type - valid data flag
- *
- * Client: Gl user
- *-----------------------------------------------------------------------------
- */
-void
-NurbsTessellator::pwlcurve( long count, INREAL array[], long byte_stride, long type )
-{
- Mapdesc *mapdesc = maplist.locate( type );
-
- if( mapdesc == 0 ) {
- do_nurbserror( 35 );
- isDataValid = 0;
- return;
- }
-
- if ( (type != N_P2D) && (type != N_P2DR) ) {
- do_nurbserror( 22 );
- isDataValid = 0;
- return;
- }
- if( count < 0 ) {
- do_nurbserror( 33 );
- isDataValid = 0;
- return;
- }
- if( byte_stride < 0 ) {
- do_nurbserror( 34 );
- isDataValid = 0;
- return;
- }
-
-#ifdef NOTDEF
- if( mapdesc->isRational() ) {
- INREAL *p = array;
- INREAL x = p[0]; INREAL y = p[1]; INREAL w = p[2];
- p = (INREAL *) (((char *) p) + byte_stride);
- for( long i = 1; i != count; i++ ) {
- if( p[0] == x && p[1] == y && p[2] == w ) break;
- x = p[0]; y = p[1]; w = p[2];
- p = (INREAL *) (((char *) p) + byte_stride);
- }
- if( i != count ) {
- do_nurbserror( 37 );
- _glu_dprintf( "point %d (%f,%f)\n", i, x, y );
- isDataValid = 0;
- return;
- }
- } else {
- INREAL *p = array;
- INREAL x = p[0]; INREAL y = p[1];
- p = (INREAL *) (((char *) p) + byte_stride);
- for( long i = 1; i != count; i++ ) {
- if( p[0] == x && p[1] == y ) break;
- x = p[0]; y = p[1];
- p = (INREAL *) (((char *) p) + byte_stride);
- }
- if( i != count ) {
- do_nurbserror( 37 );
- _glu_dprintf( "point %d (%f,%f)\n", i, x, y );
- isDataValid = 0;
- return;
- }
- }
-#endif
-
- O_pwlcurve *o_pwlcurve = new(o_pwlcurvePool) O_pwlcurve( type, count, array, byte_stride, extTrimVertexPool.get((int)count) );
- THREAD( do_pwlcurve, o_pwlcurve, do_freepwlcurve );
-}
-
-
-/*-----------------------------------------------------------------------------
- * nurbscurve -
- *
- * Client: GL user
- *-----------------------------------------------------------------------------
- */
-void
-NurbsTessellator::nurbscurve(
- long nknots, /* number of p knots */
- INREAL knot[], /* nondecreasing knot values in p */
- long byte_stride, /* distance in bytes between control points */
- INREAL ctlarray[], /* pointer to first control point */
- long order, /* order of spline */
- long type ) /* description of range space */
-{
-
- Mapdesc *mapdesc = maplist.locate( type );
-
- if( mapdesc == 0 ) {
- do_nurbserror( 35 );
- isDataValid = 0;
- return;
- }
-
- if( ctlarray == 0 ) {
- do_nurbserror( 36 );
- isDataValid = 0;
- return;
- }
-
- if( byte_stride < 0 ) {
- do_nurbserror( 34 );
- isDataValid = 0;
- return;
- }
-
- Knotvector knots;
-
- knots.init( nknots, byte_stride, order, knot );
- if( do_check_knots( &knots, "curve" ) ) return;
-
- O_nurbscurve *o_nurbscurve = new(o_nurbscurvePool) O_nurbscurve(type);
- o_nurbscurve->bezier_curves = new(quiltPool) Quilt(mapdesc);
- o_nurbscurve->bezier_curves->toBezier( knots,ctlarray, mapdesc->getNcoords() );
-
- THREAD( do_nurbscurve, o_nurbscurve, do_freenurbscurve );
-}
-
-
-/*-----------------------------------------------------------------------------
- * nurbssurface -
- *
- * Client: User routine
- *-----------------------------------------------------------------------------
- */
-void
-NurbsTessellator::nurbssurface(
- long sknot_count, /* number of s knots */
- INREAL sknot[], /* nondecreasing knot values in s */
- long tknot_count, /* number of t knots */
- INREAL tknot[], /* nondecreasing knot values in t */
- long s_byte_stride, /* s step size in memory bytes */
- long t_byte_stride, /* t step size in memory bytes */
- INREAL ctlarray[], /* pointer to first control point */
- long sorder, /* order of the spline in s parameter */
- long torder, /* order of the spline in t parameter */
- long type) /* description of range space */
-{
- Mapdesc *mapdesc = maplist.locate( type );
-
- if( mapdesc == 0 ) {
- do_nurbserror( 35 );
- isDataValid = 0;
- return;
- }
-
- if( s_byte_stride < 0 ) {
- do_nurbserror( 34 );
- isDataValid = 0;
- return;
- }
-
- if( t_byte_stride < 0 ) {
- do_nurbserror( 34 );
- isDataValid = 0;
- return;
- }
-
- Knotvector sknotvector, tknotvector;
-
- sknotvector.init( sknot_count, s_byte_stride, sorder, sknot );
- if( do_check_knots( &sknotvector, "surface" ) ) return;
-
- tknotvector.init( tknot_count, t_byte_stride, torder, tknot );
- if( do_check_knots( &tknotvector, "surface" ) ) return;
-
- O_nurbssurface *o_nurbssurface = new(o_nurbssurfacePool) O_nurbssurface(type);
- o_nurbssurface->bezier_patches = new(quiltPool) Quilt(mapdesc);
-
- o_nurbssurface->bezier_patches->toBezier( sknotvector, tknotvector,
- ctlarray, mapdesc->getNcoords() );
- THREAD( do_nurbssurface, o_nurbssurface, do_freenurbssurface );
-}
-
-
-/*-----------------------------------------------------------------------------
- * setnurbsproperty -
- *
- *-----------------------------------------------------------------------------
- */
-void
-NurbsTessellator::setnurbsproperty( long tag, INREAL value )
-{
- if( ! renderhints.isProperty( tag ) ) {
- do_nurbserror( 26 );
- } else {
- Property *prop = new(propertyPool) Property( tag, value );
- THREAD( do_setnurbsproperty, prop, do_freenurbsproperty );
- }
-}
-
-/*-----------------------------------------------------------------------------
- * setnurbsproperty -
- *
- *-----------------------------------------------------------------------------
- */
-void
-NurbsTessellator::setnurbsproperty( long type, long tag, INREAL value )
-{
- Mapdesc *mapdesc = maplist.locate( type );
-
- if( mapdesc == 0 ) {
- do_nurbserror( 35 );
- return;
- }
-
- if( ! mapdesc->isProperty( tag ) ) {
- do_nurbserror( 26 );
- return;
- }
-
- Property *prop = new(propertyPool) Property( type, tag, value );
- THREAD( do_setnurbsproperty2, prop, do_freenurbsproperty );
-}
-
-
-/*-----------------------------------------------------------------------------
- * getnurbsproperty -
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-NurbsTessellator::getnurbsproperty( long tag, INREAL *value )
-{
- if( renderhints.isProperty( tag ) ) {
- *value = renderhints.getProperty( tag );
- } else {
- do_nurbserror( 26 );
- }
-}
-
-/*-----------------------------------------------------------------------------
- * getnurbsproperty -
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-NurbsTessellator::getnurbsproperty( long type, long tag, INREAL *value )
-{
- Mapdesc *mapdesc = maplist.locate( type );
-
- if( mapdesc == 0 )
- do_nurbserror( 35 );
-
- if( mapdesc->isProperty( tag ) ) {
- *value = mapdesc->getProperty( tag );
- } else {
- do_nurbserror( 26 );
- }
-}
-
-/*--------------------------------------------------------------------------
- * setnurbsproperty - accept a user supplied matrix as culling or sampling mat
- *--------------------------------------------------------------------------
- */
-
-void
-NurbsTessellator::setnurbsproperty( long type, long purpose, INREAL *mat )
-{
- // XXX - cannot be put in display list
- Mapdesc *mapdesc = maplist.locate( type );
-
- if( mapdesc == 0 ) {
- do_nurbserror( 35 );
- isDataValid = 0;
- } else if( purpose == N_BBOXSIZE ) {
- mapdesc->setBboxsize( mat );
- } else {
-#ifndef NDEBUG
- _glu_dprintf( "ERRORRORRORR!!!\n");
-#endif
- }
-}
-
-/*--------------------------------------------------------------------------
- * setnurbsproperty - accept a user supplied matrix as culling or sampling mat
- *--------------------------------------------------------------------------
- */
-
-void
-NurbsTessellator::setnurbsproperty( long type, long purpose, INREAL *mat,
- long rstride, long cstride )
-{
- // XXX - cannot be put in display list
- Mapdesc *mapdesc = maplist.locate( type );
-
- if( mapdesc == 0 ) {
- do_nurbserror( 35 );
- isDataValid = 0;
- } else if( purpose == N_CULLINGMATRIX ) {
- mapdesc->setCmat( mat, rstride, cstride );
- } else if( purpose == N_SAMPLINGMATRIX ) {
- mapdesc->setSmat( mat, rstride, cstride );
- } else if( purpose == N_BBOXMATRIX ) {
- mapdesc->setBmat( mat, rstride, cstride );
- } else {
-#ifndef NDEBUG
- _glu_dprintf( "ERRORRORRORR!!!\n");
-#endif
- }
-}
-
-void
-NurbsTessellator::redefineMaps( void )
-{
- maplist.initialize();
-}
-
-void
-NurbsTessellator::defineMap( long type, long rational, long ncoords )
-{
- maplist.define( type, (int) rational, (int) ncoords );
-}
-
-void
-NurbsTessellator::discardRecording( void *_dl )
-{
- delete (DisplayList *) _dl;
-}
-
-void *
-NurbsTessellator::beginRecording( void )
-{
- dl = new DisplayList( this );
- return (void *) dl;
-}
-
-void
-NurbsTessellator::endRecording( void )
-{
- dl->endList();
- dl = 0;
-}
-
-void
-NurbsTessellator::playRecording( void *_dl )
-{
- playBack = 1;
- bgnrender();
- ((DisplayList *)_dl)->play();
- endrender();
- playBack = 0;
-}
-
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * nurbstess.c++
- *
- */
-
-#include "glimports.h"
-#include "myassert.h"
-#include "mysetjmp.h"
-#include "mystdio.h"
-#include "nurbsconsts.h"
-#include "nurbstess.h"
-#include "bufpool.h"
-#include "quilt.h"
-#include "knotvector.h"
-#include "mapdesc.h"
-#include "maplist.h"
-
-void
-NurbsTessellator::set_domain_distance_u_rate(REAL u_rate)
-{
- subdivider.set_domain_distance_u_rate(u_rate);
-}
-
-void
-NurbsTessellator::set_domain_distance_v_rate(REAL v_rate)
-{
- subdivider.set_domain_distance_v_rate(v_rate);
-}
-
-void
-NurbsTessellator::set_is_domain_distance_sampling(int flag)
-{
- subdivider.set_is_domain_distance_sampling(flag);
-}
-
-void
-NurbsTessellator::resetObjects( void )
-{
- subdivider.clear();
-}
-
-void
-NurbsTessellator::makeobj( int )
-{
-#ifndef NDEBUG
- _glu_dprintf( "makeobj\n" );
-#endif
-}
-
-void
-NurbsTessellator::closeobj( void )
-{
-#ifndef NDEBUG
- _glu_dprintf( "closeobj\n" );
-#endif
-}
-
-void
-NurbsTessellator::bgnrender( void )
-{
-#ifndef NDEBUG
- _glu_dprintf( "bgnrender\n" );
-#endif
-}
-
-void
-NurbsTessellator::endrender( void )
-{
-#ifndef NDEBUG
- _glu_dprintf( "endrender\n" );
-#endif
-}
-
-/*-----------------------------------------------------------------------------
- * do_freebgnsurface - free o_surface structure
- *
- * Client: do_freeall(), bgnsurface()
- *-----------------------------------------------------------------------------
- */
-void
-NurbsTessellator::do_freebgnsurface( O_surface *o_surface )
-{
- o_surface->deleteMe( o_surfacePool );
-}
-
-
-/*-----------------------------------------------------------------------------
- * do_bgnsurface - begin the display of a surface
- *
- * Client: bgnsurface()
- *-----------------------------------------------------------------------------
- */
-void
-NurbsTessellator::do_bgnsurface( O_surface *o_surface )
-{
- if( inSurface ) {
- do_nurbserror( 27 );
- endsurface();
- }
- inSurface = 1;
-
- if( ! playBack ) bgnrender();
-
- isTrimModified = 0;
- isSurfaceModified = 0;
- isDataValid = 1;
- numTrims = 0;
- currentSurface = o_surface;
- nextTrim = &( currentSurface->o_trim );
- nextNurbssurface = &( currentSurface->o_nurbssurface );
-}
-
-/*-----------------------------------------------------------------------------
- * do_bgncurve - begin the display of a curve
- *
- * Client: bgncurve()
- *-----------------------------------------------------------------------------
- */
-void
-NurbsTessellator::do_bgncurve( O_curve *o_curve )
-{
- if ( inCurve ) {
- do_nurbserror( 6 );
- endcurve();
- }
-
- inCurve = 1;
- currentCurve = o_curve;
- currentCurve->curvetype = ct_none;
-
- if( inTrim ) {
- if( *nextCurve != o_curve ) {
- isCurveModified = 1;
- *nextCurve = o_curve;
- }
- } else {
- if( ! playBack ) bgnrender();
- isDataValid = 1;
- }
- nextCurve = &(o_curve->next);
- nextPwlcurve = &(o_curve->curve.o_pwlcurve);
- nextNurbscurve = &(o_curve->curve.o_nurbscurve);
-}
-
-/*-----------------------------------------------------------------------------
- * do_endcurve -
- *
- * Client: endcurve()
- *-----------------------------------------------------------------------------
- */
-
-void
-NurbsTessellator::do_endcurve( void )
-{
- if( ! inCurve ) {
- do_nurbserror( 7 );
- return;
- }
- inCurve = 0;
-
- *nextCurve = 0;
- if (currentCurve->curvetype == ct_nurbscurve)
- *nextNurbscurve = 0;
- else
- *nextPwlcurve = 0;
-
- if ( ! inTrim ) {
- if( ! isDataValid ) {
- do_freecurveall( currentCurve );
- return;
- }
-
- int errval;
- errval = ::mysetjmp( jumpbuffer );
- if( errval == 0 ) {
- if( currentCurve->curvetype == ct_nurbscurve ) {
- subdivider.beginQuilts();
- for( O_nurbscurve *n = currentCurve->curve.o_nurbscurve; n != 0; n = n->next )
- subdivider.addQuilt( n->bezier_curves );
- subdivider.endQuilts();
- subdivider.drawCurves();
- if( ! playBack ) endrender();
- } else {
- /* XXX */
- if( ! playBack ) endrender();
- /*do_draw_pwlcurve( currentCurve->curve.o_pwlcurve ) */;
- do_nurbserror( 9 );
- }
- } else {
- if( ! playBack ) endrender();
- do_nurbserror( errval );
- }
- do_freecurveall( currentCurve );
- resetObjects();
- }
-}
-
-/*-----------------------------------------------------------------------------
- * do_endsurface - mark end of surface, display surface, free immediate data
- *
- * Client:
- *-----------------------------------------------------------------------------
- */
-void
-NurbsTessellator::do_endsurface( void )
-{
- if( inTrim ) {
- do_nurbserror( 12 );
- endtrim();
- }
-
- if( ! inSurface ) {
- do_nurbserror( 13 );
- return;
- }
- inSurface = 0;
-
- *nextNurbssurface = 0;
-
- if( ! isDataValid ) {
- do_freeall( );
- return;
- }
-
- if( *nextTrim != 0 ) {
- isTrimModified = 1;
- *nextTrim = 0;
- }
-
- int errval;
-
- errval = ::mysetjmp( jumpbuffer );
- if( errval == 0 ) {
- if( numTrims > 0 ) {
-
- subdivider.beginTrims();
- for( O_trim *trim = currentSurface->o_trim; trim; trim = trim->next ) {
- subdivider.beginLoop();
- for( O_curve *curve = trim->o_curve; curve; curve = curve->next ) {
- curve->used = 0;
- assert( curve->curvetype != ct_none );
- if (curve->curvetype == ct_pwlcurve) {
- O_pwlcurve *c = curve->curve.o_pwlcurve;
- subdivider.addArc( c->npts, c->pts, curve->nuid );
- } else {
- Quilt *quilt = curve->curve.o_nurbscurve->bezier_curves;
- Quiltspec *qspec = quilt->qspec;
- REAL *cpts = quilt->cpts + qspec->offset;
- REAL *cptsend = cpts + (qspec->width * qspec->order * qspec->stride);
- for( ; cpts != cptsend; cpts += qspec->order*qspec->stride )
- subdivider.addArc( cpts, quilt, curve->nuid );
- }
- }
- subdivider.endLoop();
- }
- subdivider.endTrims();
- }
-
- subdivider.beginQuilts();
- for( O_nurbssurface *n = currentSurface->o_nurbssurface; n; n = n->next )
- subdivider.addQuilt( n->bezier_patches );
- subdivider.endQuilts();
- subdivider.drawSurfaces( currentSurface->nuid );
- if( ! playBack ) endrender();
- } else {
- if( ! playBack ) endrender();
- do_nurbserror( errval );
- }
-
- do_freeall( );
- resetObjects();
-}
-
-/*-----------------------------------------------------------------------------
- * do_freeall - free all data allocated in immediate mode
- *
- * Client:
- *-----------------------------------------------------------------------------
- */
-void
-NurbsTessellator::do_freeall( void )
-{
- for( O_trim *o_trim = currentSurface->o_trim; o_trim; ) {
- O_trim *next_o_trim = o_trim->next;
- for( O_curve *curve = o_trim->o_curve; curve; ) {
- O_curve *next_o_curve = curve->next;
- do_freecurveall( curve );
- curve = next_o_curve;
- }
- if( o_trim->save == 0 ) do_freebgntrim( o_trim );
- o_trim = next_o_trim;
- }
-
- O_nurbssurface *nurbss, *next_nurbss;
- for( nurbss= currentSurface->o_nurbssurface; nurbss; nurbss = next_nurbss) {
- next_nurbss = nurbss->next;
- if( nurbss->save == 0 )
- do_freenurbssurface( nurbss );
- else
- nurbss->used = 0;
- }
-
- if( currentSurface->save == 0 ) do_freebgnsurface( currentSurface );
-}
-
-void
-NurbsTessellator::do_freecurveall( O_curve *curve )
-{
- assert( curve->curvetype != ct_none );
-
- if( curve->curvetype == ct_nurbscurve ) {
- O_nurbscurve *ncurve, *next_ncurve;
- for( ncurve=curve->curve.o_nurbscurve; ncurve; ncurve=next_ncurve ) {
- next_ncurve = ncurve->next;
- if( ncurve->save == 0 )
- do_freenurbscurve( ncurve );
- else
- ncurve->used = 0;
- }
- } else {
- O_pwlcurve *pcurve, *next_pcurve;
- for( pcurve=curve->curve.o_pwlcurve; pcurve; pcurve=next_pcurve ) {
- next_pcurve = pcurve->next;
- if( pcurve->save == 0 )
- do_freepwlcurve( pcurve );
- else
- pcurve->used = 0;
- }
- }
- if( curve->save == 0 )
- do_freebgncurve( curve );
-}
-
-
-/*-----------------------------------------------------------------------------
- * do_freebgntrim - free the space allocated for a trim loop
- *
- * Client:
- *-----------------------------------------------------------------------------
- */
-void
-NurbsTessellator::do_freebgntrim( O_trim *o_trim )
-{
- o_trim->deleteMe( o_trimPool );
-}
-
-
-/*-----------------------------------------------------------------------------
- * do_bgntrim - link in a trim loop to the current trimmed surface description
- *
- * Client: bgntrim()
- *-----------------------------------------------------------------------------
- */
-void
-NurbsTessellator::do_bgntrim( O_trim *o_trim )
-{
-
- if( ! inSurface ) {
- do_nurbserror( 15 );
- bgnsurface( 0 );
- inSurface = 2;
- }
-
- if( inTrim ) {
- do_nurbserror( 16 );
- endtrim();
- }
- inTrim = 1;
-
- if( *nextTrim != o_trim ) {
- isTrimModified = 1;
- *nextTrim = o_trim;
- }
-
- currentTrim = o_trim;
- nextTrim = &(o_trim->next);
- nextCurve = &(o_trim->o_curve);
-}
-
-
-/*-----------------------------------------------------------------------------
- * do_endtrim - mark the end of the current trim loop
- *
- * Client: endtrim()
- *-----------------------------------------------------------------------------
- */
-void
-NurbsTessellator::do_endtrim( void )
-{
- if( ! inTrim ) {
- do_nurbserror( 17 );
- return;
- }
- inTrim = 0;
-
- if( currentTrim->o_curve == 0 ) {
- do_nurbserror( 18 );
- isDataValid = 0;
- }
-
- numTrims++;
-
- if( *nextCurve != 0 ) {
- isTrimModified = 1;
- *nextCurve = 0;
- }
-}
-
-/*-----------------------------------------------------------------------------
- * do_freepwlcurve -
- *
- * Client:
- *-----------------------------------------------------------------------------
- */
-void
-NurbsTessellator::do_freepwlcurve( O_pwlcurve *o_pwlcurve )
-{
- o_pwlcurve->deleteMe( o_pwlcurvePool );
-}
-
-void
-NurbsTessellator::do_freebgncurve( O_curve *o_curve )
-{
- o_curve->deleteMe( o_curvePool );
-}
-
-/*-----------------------------------------------------------------------------
- * do_pwlcurve - link in pwl trim loop to the current surface description
- *
- * Client: pwlcurve()
- *-----------------------------------------------------------------------------
- */
-void
-NurbsTessellator::do_pwlcurve( O_pwlcurve *o_pwlcurve )
-{
- if( ! inTrim ) {
- do_nurbserror( 19 );
- if( o_pwlcurve->save == 0 )
- do_freepwlcurve(o_pwlcurve );
- return;
- }
-
- if( ! inCurve ) {
- bgncurve( 0 );
- inCurve = 2;
- }
-
- if( o_pwlcurve->used ) {
- do_nurbserror( 20 );
- isDataValid = 0;
- return;
- } else
- o_pwlcurve->used = 1;
-
- if( currentCurve->curvetype == ct_none ) {
- currentCurve->curvetype = ct_pwlcurve;
- } else if( currentCurve->curvetype != ct_pwlcurve ) {
- do_nurbserror( 21 );
- isDataValid = 0;
- return;
- }
-
- if( *nextPwlcurve != o_pwlcurve ) {
- isCurveModified = 1;
- *nextPwlcurve = o_pwlcurve;
- }
- nextPwlcurve = &(o_pwlcurve->next);
-
- if( o_pwlcurve->owner != currentCurve ) {
- isCurveModified = 1;
- o_pwlcurve->owner = currentCurve;
- }
-
- if( inCurve == 2 )
- endcurve();
-}
-
-
-/*-----------------------------------------------------------------------------
- * do_freenurbscurve -
- *
- * Client:
- *-----------------------------------------------------------------------------
- */
-void
-NurbsTessellator::do_freenurbscurve( O_nurbscurve *o_nurbscurve )
-{
- o_nurbscurve->bezier_curves->deleteMe( quiltPool );
- o_nurbscurve->deleteMe( o_nurbscurvePool );
-}
-
-
-/*-----------------------------------------------------------------------------
- * do_nurbscurve -
- *
- * Client: nurbscurve()
- *-----------------------------------------------------------------------------
- */
-void
-NurbsTessellator::do_nurbscurve( O_nurbscurve *o_nurbscurve )
-{
- if ( ! inCurve ) {
- bgncurve( 0 );
- inCurve = 2;
- }
-
- if( o_nurbscurve->used ) {
- /* error - curve was already called in current surface */
- do_nurbserror( 23 );
- isDataValid = 0;
- return;
- } else
- o_nurbscurve->used = 1;
-
- if( currentCurve->curvetype == ct_none ) {
- currentCurve->curvetype = ct_nurbscurve;
- } else if( currentCurve->curvetype != ct_nurbscurve ) {
- do_nurbserror( 24 );
- isDataValid = 0;
- return;
- }
-
- if( *nextNurbscurve != o_nurbscurve ) {
- isCurveModified = 1;
- *nextNurbscurve = o_nurbscurve;
- }
-
- nextNurbscurve = &(o_nurbscurve->next);
-
- if( o_nurbscurve->owner != currentCurve ) {
- isCurveModified = 1;
- o_nurbscurve->owner = currentCurve;
- }
-
- if( o_nurbscurve->owner == 0 )
- isCurveModified = 1;
-
- if( inCurve == 2 )
- endcurve();
-}
-
-
-/*-----------------------------------------------------------------------------
- * do_freenurbssurface -
- *
- * Client:
- *-----------------------------------------------------------------------------
- */
-
-void
-NurbsTessellator::do_freenurbssurface( O_nurbssurface *o_nurbssurface )
-{
- o_nurbssurface->bezier_patches->deleteMe( quiltPool );
- o_nurbssurface->deleteMe( o_nurbssurfacePool );
-}
-
-/*-----------------------------------------------------------------------------
- * do_nurbssurface -
- *
- * Client: nurbssurface()
- *-----------------------------------------------------------------------------
- */
-void
-NurbsTessellator::do_nurbssurface( O_nurbssurface *o_nurbssurface )
-{
- if( ! inSurface ) {
- bgnsurface( 0 );
- inSurface = 2;
- }
-
- if( o_nurbssurface->used ) {
- /* error - surface was already called in current block */
- do_nurbserror( 25 );
- isDataValid = 0;
- return;
- } else
- o_nurbssurface->used = 1;
-
- if( *nextNurbssurface != o_nurbssurface ) {
- isSurfaceModified = 1;
- *nextNurbssurface = o_nurbssurface;
- }
-
- if( o_nurbssurface->owner != currentSurface ) {
- isSurfaceModified = 1;
- o_nurbssurface->owner = currentSurface;
- }
- nextNurbssurface = &(o_nurbssurface->next);
-
- if( inSurface == 2 )
- endsurface();
-}
-
-
-/*-----------------------------------------------------------------------------
- * do_freenurbsproperty
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-NurbsTessellator::do_freenurbsproperty( Property *prop )
-{
- prop->deleteMe( propertyPool );
-}
-
-
-/*-----------------------------------------------------------------------------
- * do_setnurbsproperty -
- *
- *-----------------------------------------------------------------------------
- */
-
-void
-NurbsTessellator::do_setnurbsproperty( Property *prop )
-{
- renderhints.setProperty( prop->tag, prop->value );
- if( prop->save == 0 )
- do_freenurbsproperty( prop );
-}
-
-void
-NurbsTessellator::do_setnurbsproperty2( Property *prop )
-{
- Mapdesc *mapdesc = maplist.find( prop->type );
-
- mapdesc->setProperty( prop->tag, prop->value );
- if( prop->save == 0 )
- do_freenurbsproperty( prop );
-}
-
-void
-NurbsTessellator::errorHandler( int )
-{
-}
-
-void
-NurbsTessellator::do_nurbserror( int msg )
-{
- errorHandler( msg );
-}
-
-int
-NurbsTessellator::do_check_knots( Knotvector *knots, const char *msg )
-{
- int status = knots->validate();
- if( status ) {
- do_nurbserror( status );
- if( renderhints.errorchecking != N_NOMSG ) knots->show( msg );
- }
- return status;
-}
-
-
-
-
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * nurbstess.h
- *
- */
-
-#ifndef __glunurbstess_h_
-#define __glunurbstess_h_
-
-#include "mysetjmp.h"
-#include "subdivider.h"
-#include "renderhints.h"
-#include "backend.h"
-#include "maplist.h"
-#include "reader.h"
-#include "nurbsconsts.h"
-
-struct Knotvector;
-class Quilt;
-class DisplayList;
-class BasicCurveEvaluator;
-class BasicSurfaceEvaluator;
-
-class NurbsTessellator {
-public:
- NurbsTessellator( BasicCurveEvaluator &c,
- BasicSurfaceEvaluator &e );
- virtual ~NurbsTessellator( void );
-
- void getnurbsproperty( long, INREAL * );
- void getnurbsproperty( long, long, INREAL * );
- void setnurbsproperty( long, INREAL );
- void setnurbsproperty( long, long, INREAL );
- void setnurbsproperty( long, long, INREAL * );
- void setnurbsproperty( long, long, INREAL *, long, long );
-
- // called before a tessellation begins/ends
- virtual void bgnrender( void );
- virtual void endrender( void );
-
- // called to make a display list of the output vertices
- virtual void makeobj( int n );
- virtual void closeobj( void );
-
- // called when a error occurs
- virtual void errorHandler( int );
-
- void bgnsurface( long );
- void endsurface( void );
- void bgntrim( void );
- void endtrim( void );
- void bgncurve( long );
- void endcurve( void );
- void pwlcurve( long, INREAL[], long, long );
- void nurbscurve( long, INREAL[], long, INREAL[], long, long );
- void nurbssurface( long, INREAL[], long, INREAL[], long, long,
- INREAL[], long, long, long );
-
- void defineMap( long, long, long );
- void redefineMaps( void );
-
- // recording of input description
- void discardRecording( void * );
- void * beginRecording( void );
- void endRecording( void );
- void playRecording( void * );
-
- //for optimizing untrimmed nurbs in the case of domain distance sampling
- void set_domain_distance_u_rate(REAL u_rate);
- void set_domain_distance_v_rate(REAL v_rate);
- void set_is_domain_distance_sampling(int flag);
-
-
-protected:
- Renderhints renderhints;
- Maplist maplist;
- Backend backend;
-
-private:
-
- void resetObjects( void );
- int do_check_knots( Knotvector *, const char * );
- void do_nurbserror( int );
- void do_bgncurve( O_curve * );
- void do_endcurve( void );
- void do_freeall( void );
- void do_freecurveall( O_curve * );
- void do_freebgntrim( O_trim * );
- void do_freebgncurve( O_curve * );
- void do_freepwlcurve( O_pwlcurve * );
- void do_freenurbscurve( O_nurbscurve * );
- void do_freenurbssurface( O_nurbssurface * );
- void do_freebgnsurface( O_surface * );
- void do_bgnsurface( O_surface * );
- void do_endsurface( void );
- void do_bgntrim( O_trim * );
- void do_endtrim( void );
- void do_pwlcurve( O_pwlcurve * );
- void do_nurbscurve( O_nurbscurve * );
- void do_nurbssurface( O_nurbssurface * );
- void do_freenurbsproperty( Property * );
- void do_setnurbsproperty( Property * );
- void do_setnurbsproperty2( Property * );
-
- Subdivider subdivider;
- JumpBuffer* jumpbuffer;
- Pool o_pwlcurvePool;
- Pool o_nurbscurvePool;
- Pool o_curvePool;
- Pool o_trimPool;
- Pool o_surfacePool;
- Pool o_nurbssurfacePool;
- Pool propertyPool;
-public:
- Pool quiltPool;
-private:
- TrimVertexPool extTrimVertexPool;
-
- int inSurface; /* bgnsurface seen */
- int inCurve; /* bgncurve seen */
- int inTrim; /* bgntrim seen */
- int isCurveModified; /* curve changed */
- int isTrimModified; /* trim curves changed */
- int isSurfaceModified; /* surface changed */
- int isDataValid; /* all data is good */
- int numTrims; /* valid trim regions */
- int playBack;
-
- O_trim** nextTrim; /* place to link o_trim */
- O_curve** nextCurve; /* place to link o_curve */
- O_nurbscurve** nextNurbscurve; /* place to link o_nurbscurve */
- O_pwlcurve** nextPwlcurve; /* place to link o_pwlcurve */
- O_nurbssurface** nextNurbssurface; /* place to link o_nurbssurface */
-
- O_surface* currentSurface;
- O_trim* currentTrim;
- O_curve* currentCurve;
-
- DisplayList *dl;
-
-};
-
-#endif /* __glunurbstess_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * patch.c++
- *
- */
-
-#include <stdio.h>
-#include "glimports.h"
-#include "mystdio.h"
-#include "myassert.h"
-#include "mymath.h"
-#include "mystring.h"
-#include "patch.h"
-#include "mapdesc.h"
-#include "quilt.h"
-#include "nurbsconsts.h"
-#include "simplemath.h" //for glu_abs function in ::singleStep();
-
-
-/*--------------------------------------------------------------------------
- * Patch - copy patch from quilt and transform control points
- *--------------------------------------------------------------------------
- */
-
-Patch::Patch( Quilt_ptr geo, REAL *pta, REAL *ptb, Patch *n )
-{
-/* pspec[i].range is uninit here */
- mapdesc = geo->mapdesc;
- cullval = mapdesc->isCulling() ? CULL_ACCEPT : CULL_TRIVIAL_ACCEPT;
- notInBbox = mapdesc->isBboxSubdividing() ? 1 : 0;
- needsSampling = mapdesc->isRangeSampling() ? 1 : 0;
- pspec[0].order = geo->qspec[0].order;
- pspec[1].order = geo->qspec[1].order;
- pspec[0].stride = pspec[1].order * MAXCOORDS;
- pspec[1].stride = MAXCOORDS;
-
- /* transform control points to sampling and culling spaces */
- REAL *ps = geo->cpts;
- geo->select( pta, ptb );
- ps += geo->qspec[0].offset;
- ps += geo->qspec[1].offset;
- ps += geo->qspec[0].index * geo->qspec[0].order * geo->qspec[0].stride;
- ps += geo->qspec[1].index * geo->qspec[1].order * geo->qspec[1].stride;
-
- if( needsSampling ) {
- mapdesc->xformSampling( ps, geo->qspec[0].order, geo->qspec[0].stride,
- geo->qspec[1].order, geo->qspec[1].stride,
- spts, pspec[0].stride, pspec[1].stride );
- }
-
- if( cullval == CULL_ACCEPT ) {
- mapdesc->xformCulling( ps, geo->qspec[0].order, geo->qspec[0].stride,
- geo->qspec[1].order, geo->qspec[1].stride,
- cpts, pspec[0].stride, pspec[1].stride );
- }
-
- if( notInBbox ) {
- mapdesc->xformBounding( ps, geo->qspec[0].order, geo->qspec[0].stride,
- geo->qspec[1].order, geo->qspec[1].stride,
- bpts, pspec[0].stride, pspec[1].stride );
- }
-
- /* set scale range */
- pspec[0].range[0] = geo->qspec[0].breakpoints[geo->qspec[0].index];
- pspec[0].range[1] = geo->qspec[0].breakpoints[geo->qspec[0].index+1];
- pspec[0].range[2] = pspec[0].range[1] - pspec[0].range[0];
-
- pspec[1].range[0] = geo->qspec[1].breakpoints[geo->qspec[1].index];
- pspec[1].range[1] = geo->qspec[1].breakpoints[geo->qspec[1].index+1];
- pspec[1].range[2] = pspec[1].range[1] - pspec[1].range[0];
-
- // may need to subdivide to match range of sub-patch
- if( pspec[0].range[0] != pta[0] ) {
- assert( pspec[0].range[0] < pta[0] );
- Patch lower( *this, 0, pta[0], 0 );
- *this = lower;
- }
-
- if( pspec[0].range[1] != ptb[0] ) {
- assert( pspec[0].range[1] > ptb[0] );
- Patch upper( *this, 0, ptb[0], 0 );
- }
-
- if( pspec[1].range[0] != pta[1] ) {
- assert( pspec[1].range[0] < pta[1] );
- Patch lower( *this, 1, pta[1], 0 );
- *this = lower;
- }
-
- if( pspec[1].range[1] != ptb[1] ) {
- assert( pspec[1].range[1] > ptb[1] );
- Patch upper( *this, 1, ptb[1], 0 );
- }
- checkBboxConstraint();
- next = n;
-}
-
-/*--------------------------------------------------------------------------
- * Patch - subdivide a patch along an isoparametric line
- *--------------------------------------------------------------------------
- */
-
-Patch::Patch( Patch& upper, int param, REAL value, Patch *n )
-{
- Patch& lower = *this;
-
- lower.cullval = upper.cullval;
- lower.mapdesc = upper.mapdesc;
- lower.notInBbox = upper.notInBbox;
- lower.needsSampling = upper.needsSampling;
- lower.pspec[0].order = upper.pspec[0].order;
- lower.pspec[1].order = upper.pspec[1].order;
- lower.pspec[0].stride = upper.pspec[0].stride;
- lower.pspec[1].stride = upper.pspec[1].stride;
- lower.next = n;
-
- /* reset scale range */
- switch( param ) {
- case 0: {
- REAL d = (value-upper.pspec[0].range[0]) / upper.pspec[0].range[2];
- if( needsSampling )
- mapdesc->subdivide( upper.spts, lower.spts, d, pspec[1].order,
- pspec[1].stride, pspec[0].order, pspec[0].stride );
-
- if( cullval == CULL_ACCEPT )
- mapdesc->subdivide( upper.cpts, lower.cpts, d, pspec[1].order,
- pspec[1].stride, pspec[0].order, pspec[0].stride );
-
- if( notInBbox )
- mapdesc->subdivide( upper.bpts, lower.bpts, d, pspec[1].order,
- pspec[1].stride, pspec[0].order, pspec[0].stride );
-
- lower.pspec[0].range[0] = upper.pspec[0].range[0];
- lower.pspec[0].range[1] = value;
- lower.pspec[0].range[2] = value - upper.pspec[0].range[0];
- upper.pspec[0].range[0] = value;
- upper.pspec[0].range[2] = upper.pspec[0].range[1] - value;
-
- lower.pspec[1].range[0] = upper.pspec[1].range[0];
- lower.pspec[1].range[1] = upper.pspec[1].range[1];
- lower.pspec[1].range[2] = upper.pspec[1].range[2];
- break;
- }
- case 1: {
- REAL d = (value-upper.pspec[1].range[0]) / upper.pspec[1].range[2];
- if( needsSampling )
- mapdesc->subdivide( upper.spts, lower.spts, d, pspec[0].order,
- pspec[0].stride, pspec[1].order, pspec[1].stride );
- if( cullval == CULL_ACCEPT )
- mapdesc->subdivide( upper.cpts, lower.cpts, d, pspec[0].order,
- pspec[0].stride, pspec[1].order, pspec[1].stride );
- if( notInBbox )
- mapdesc->subdivide( upper.bpts, lower.bpts, d, pspec[0].order,
- pspec[0].stride, pspec[1].order, pspec[1].stride );
- lower.pspec[0].range[0] = upper.pspec[0].range[0];
- lower.pspec[0].range[1] = upper.pspec[0].range[1];
- lower.pspec[0].range[2] = upper.pspec[0].range[2];
-
- lower.pspec[1].range[0] = upper.pspec[1].range[0];
- lower.pspec[1].range[1] = value;
- lower.pspec[1].range[2] = value - upper.pspec[1].range[0];
- upper.pspec[1].range[0] = value;
- upper.pspec[1].range[2] = upper.pspec[1].range[1] - value;
- break;
- }
- }
-
- // inherit bounding box
- if( mapdesc->isBboxSubdividing() && ! notInBbox )
- memcpy( lower.bb, upper.bb, sizeof( bb ) );
-
- lower.checkBboxConstraint();
- upper.checkBboxConstraint();
-}
-
-/*--------------------------------------------------------------------------
- * clamp - clamp the sampling rate to a given maximum
- *--------------------------------------------------------------------------
- */
-
-void
-Patch::clamp( void )
-{
- if( mapdesc->clampfactor != N_NOCLAMPING ) {
- pspec[0].clamp( mapdesc->clampfactor );
- pspec[1].clamp( mapdesc->clampfactor );
- }
-}
-
-void
-Patchspec::clamp( REAL clampfactor )
-{
- if( sidestep[0] < minstepsize )
- sidestep[0] = clampfactor * minstepsize;
- if( sidestep[1] < minstepsize )
- sidestep[1] = clampfactor * minstepsize;
- if( stepsize < minstepsize )
- stepsize = clampfactor * minstepsize;
-}
-
-void
-Patch::checkBboxConstraint( void )
-{
- if( notInBbox &&
- mapdesc->bboxTooBig( bpts, pspec[0].stride, pspec[1].stride,
- pspec[0].order, pspec[1].order, bb ) != 1 ) {
- notInBbox = 0;
- }
-}
-
-void
-Patch::bbox( void )
-{
- if( mapdesc->isBboxSubdividing() )
- mapdesc->surfbbox( bb );
-}
-
-/*--------------------------------------------------------------------------
- * getstepsize - compute the sampling density across the patch
- * and determine if patch needs to be subdivided
- *--------------------------------------------------------------------------
- */
-
-void
-Patch::getstepsize( void )
-{
- pspec[0].minstepsize = pspec[1].minstepsize = 0;
- pspec[0].needsSubdivision = pspec[1].needsSubdivision = 0;
-
- if( mapdesc->isConstantSampling() ) {
- // fixed number of samples per patch in each direction
- // maxsrate is number of s samples per patch
- // maxtrate is number of t samples per patch
- pspec[0].getstepsize( mapdesc->maxsrate );
- pspec[1].getstepsize( mapdesc->maxtrate );
-
- } else if( mapdesc->isDomainSampling() ) {
- // maxsrate is number of s samples per unit s length of domain
- // maxtrate is number of t samples per unit t length of domain
- pspec[0].getstepsize( mapdesc->maxsrate * pspec[0].range[2] );
- pspec[1].getstepsize( mapdesc->maxtrate * pspec[1].range[2] );
-
- } else if( ! needsSampling ) {
- pspec[0].singleStep();
- pspec[1].singleStep();
- } else {
- // upper bound on path length between sample points
- REAL tmp[MAXORDER][MAXORDER][MAXCOORDS];
- const int trstride = sizeof(tmp[0]) / sizeof(REAL);
- const int tcstride = sizeof(tmp[0][0]) / sizeof(REAL);
-
- assert( pspec[0].order <= MAXORDER );
-
- /* points have been transformed, therefore they are homogeneous */
-
- int val = mapdesc->project( spts, pspec[0].stride, pspec[1].stride,
- &tmp[0][0][0], trstride, tcstride,
- pspec[0].order, pspec[1].order );
- if( val == 0 ) {
- // control points cross infinity, therefore partials are undefined
- pspec[0].getstepsize( mapdesc->maxsrate );
- pspec[1].getstepsize( mapdesc->maxtrate );
- } else {
- REAL t1 = mapdesc->getProperty( N_PIXEL_TOLERANCE );
-// REAL t2 = mapdesc->getProperty( N_ERROR_TOLERANCE );
- pspec[0].minstepsize = ( mapdesc->maxsrate > 0.0 ) ?
- (pspec[0].range[2] / mapdesc->maxsrate) : 0.0;
- pspec[1].minstepsize = ( mapdesc->maxtrate > 0.0 ) ?
- (pspec[1].range[2] / mapdesc->maxtrate) : 0.0;
- if( mapdesc->isParametricDistanceSampling() ||
- mapdesc->isObjectSpaceParaSampling() ) {
-
- REAL t2;
- t2 = mapdesc->getProperty( N_ERROR_TOLERANCE );
-
- // t2 is upper bound on the distance between surface and tessellant
- REAL ssv[2], ttv[2];
- REAL ss = mapdesc->calcPartialVelocity( ssv, &tmp[0][0][0], trstride, tcstride, pspec[0].order, pspec[1].order, 2, 0, pspec[0].range[2], pspec[1].range[2], 0 );
- REAL st = mapdesc->calcPartialVelocity( 0, &tmp[0][0][0], trstride, tcstride, pspec[0].order, pspec[1].order, 1, 1, pspec[0].range[2], pspec[1].range[2], -1 );
- REAL tt = mapdesc->calcPartialVelocity( ttv, &tmp[0][0][0], trstride, tcstride, pspec[0].order, pspec[1].order, 0, 2, pspec[0].range[2], pspec[1].range[2], 1 );
- //make sure that ss st and tt are nonnegative:
- if(ss <0) ss = -ss;
- if(st <0) st = -st;
- if(tt <0) tt = -tt;
-
- if( ss != 0.0 && tt != 0.0 ) {
- /* printf( "ssv[0] %g ssv[1] %g ttv[0] %g ttv[1] %g\n",
- ssv[0], ssv[1], ttv[0], ttv[1] ); */
- REAL ttq = sqrtf( (float) ss );
- REAL ssq = sqrtf( (float) tt );
- REAL ds = sqrtf( 4 * t2 * ttq / ( ss * ttq + st * ssq ) );
- REAL dt = sqrtf( 4 * t2 * ssq / ( tt * ssq + st * ttq ) );
- pspec[0].stepsize = ( ds < pspec[0].range[2] ) ? ds : pspec[0].range[2];
- REAL scutoff = 2.0 * t2 / ( pspec[0].range[2] * pspec[0].range[2]);
- pspec[0].sidestep[0] = (ssv[0] > scutoff) ? sqrtf( 2.0 * t2 / ssv[0] ) : pspec[0].range[2];
- pspec[0].sidestep[1] = (ssv[1] > scutoff) ? sqrtf( 2.0 * t2 / ssv[1] ) : pspec[0].range[2];
-
- pspec[1].stepsize = ( dt < pspec[1].range[2] ) ? dt : pspec[1].range[2];
- REAL tcutoff = 2.0 * t2 / ( pspec[1].range[2] * pspec[1].range[2]);
- pspec[1].sidestep[0] = (ttv[0] > tcutoff) ? sqrtf( 2.0 * t2 / ttv[0] ) : pspec[1].range[2];
- pspec[1].sidestep[1] = (ttv[1] > tcutoff) ? sqrtf( 2.0 * t2 / ttv[1] ) : pspec[1].range[2];
- } else if( ss != 0.0 ) {
- REAL x = pspec[1].range[2] * st;
- REAL ds = ( sqrtf( x * x + 8.0 * t2 * ss ) - x ) / ss;
- pspec[0].stepsize = ( ds < pspec[0].range[2] ) ? ds : pspec[0].range[2];
- REAL scutoff = 2.0 * t2 / ( pspec[0].range[2] * pspec[0].range[2]);
- pspec[0].sidestep[0] = (ssv[0] > scutoff) ? sqrtf( 2.0 * t2 / ssv[0] ) : pspec[0].range[2];
- pspec[0].sidestep[1] = (ssv[1] > scutoff) ? sqrtf( 2.0 * t2 / ssv[1] ) : pspec[0].range[2];
- pspec[1].singleStep();
- } else if( tt != 0.0 ) {
- REAL x = pspec[0].range[2] * st;
- REAL dt = ( sqrtf( x * x + 8.0 * t2 * tt ) - x ) / tt;
- pspec[0].singleStep();
- REAL tcutoff = 2.0 * t2 / ( pspec[1].range[2] * pspec[1].range[2]);
- pspec[1].stepsize = ( dt < pspec[1].range[2] ) ? dt : pspec[1].range[2];
- pspec[1].sidestep[0] = (ttv[0] > tcutoff) ? sqrtf( 2.0 * t2 / ttv[0] ) : pspec[1].range[2];
- pspec[1].sidestep[1] = (ttv[1] > tcutoff) ? sqrtf( 2.0 * t2 / ttv[1] ) : pspec[1].range[2];
- } else {
- if( 4.0 * t2 > st * pspec[0].range[2] * pspec[1].range[2] ) {
- pspec[0].singleStep();
- pspec[1].singleStep();
- } else {
- REAL area = 4.0 * t2 / st;
- REAL ds = sqrtf( area * pspec[0].range[2] / pspec[1].range[2] );
- REAL dt = sqrtf( area * pspec[1].range[2] / pspec[0].range[2] );
- pspec[0].stepsize = ( ds < pspec[0].range[2] ) ? ds : pspec[0].range[2];
- pspec[0].sidestep[0] = pspec[0].range[2];
- pspec[0].sidestep[1] = pspec[0].range[2];
-
- pspec[1].stepsize = ( dt < pspec[1].range[2] ) ? dt : pspec[1].range[2];
- pspec[1].sidestep[0] = pspec[1].range[2];
- pspec[1].sidestep[1] = pspec[1].range[2];
- }
- }
- } else if( mapdesc->isPathLengthSampling() ||
- mapdesc->isObjectSpacePathSampling()) {
- // t1 is upper bound on path length
- REAL msv[2], mtv[2];
- REAL ms = mapdesc->calcPartialVelocity( msv, &tmp[0][0][0], trstride, tcstride, pspec[0].order, pspec[1].order, 1, 0, pspec[0].range[2], pspec[1].range[2], 0 );
- REAL mt = mapdesc->calcPartialVelocity( mtv, &tmp[0][0][0], trstride, tcstride, pspec[0].order, pspec[1].order, 0, 1, pspec[0].range[2], pspec[1].range[2], 1 );
- REAL side_scale = 1.0;
-
- if( ms != 0.0 ) {
- if( mt != 0.0 ) {
-/* REAL d = t1 / ( ms * ms + mt * mt );*/
-/* REAL ds = mt * d;*/
- REAL ds = t1 / (2.0*ms);
-/* REAL dt = ms * d;*/
- REAL dt = t1 / (2.0*mt);
- pspec[0].stepsize = ( ds < pspec[0].range[2] ) ? ds : pspec[0].range[2];
- pspec[0].sidestep[0] = ( msv[0] * pspec[0].range[2] > t1 ) ? (side_scale* t1 / msv[0]) : pspec[0].range[2];
- pspec[0].sidestep[1] = ( msv[1] * pspec[0].range[2] > t1 ) ? (side_scale* t1 / msv[1]) : pspec[0].range[2];
-
- pspec[1].stepsize = ( dt < pspec[1].range[2] ) ? dt : pspec[1].range[2];
- pspec[1].sidestep[0] = ( mtv[0] * pspec[1].range[2] > t1 ) ? (side_scale*t1 / mtv[0]) : pspec[1].range[2];
- pspec[1].sidestep[1] = ( mtv[1] * pspec[1].range[2] > t1 ) ? (side_scale*t1 / mtv[1]) : pspec[1].range[2];
- } else {
- pspec[0].stepsize = ( t1 < ms * pspec[0].range[2] ) ? (t1 / ms) : pspec[0].range[2];
- pspec[0].sidestep[0] = ( msv[0] * pspec[0].range[2] > t1 ) ? (t1 / msv[0]) : pspec[0].range[2];
- pspec[0].sidestep[1] = ( msv[1] * pspec[0].range[2] > t1 ) ? (t1 / msv[1]) : pspec[0].range[2];
-
- pspec[1].singleStep();
- }
- } else {
- if( mt != 0.0 ) {
- pspec[0].singleStep();
-
- pspec[1].stepsize = ( t1 < mt * pspec[1].range[2] ) ? (t1 / mt) : pspec[1].range[2];
- pspec[1].sidestep[0] = ( mtv[0] * pspec[1].range[2] > t1 ) ? (t1 / mtv[0]) : pspec[1].range[2];
- pspec[1].sidestep[1] = ( mtv[1] * pspec[1].range[2] > t1 ) ? (t1 / mtv[1]) : pspec[1].range[2];
- } else {
- pspec[0].singleStep();
- pspec[1].singleStep();
- }
- }
- } else if( mapdesc->isSurfaceAreaSampling() ) {
- // t is the square root of area
-/*
- REAL msv[2], mtv[2];
- REAL ms = mapdesc->calcPartialVelocity( msv, &tmp[0][0][0], trstride, tcstride, pspec[0].order, pspec[1].order, 1, 0, pspec[0].range[2], pspec[1].range[2], 0 );
- REAL mt = mapdesc->calcPartialVelocity( mtv, &tmp[0][0][0], trstride, tcstride, pspec[0].order, pspec[1].order, 0, 1, pspec[0].range[2], pspec[1].range[2], 1 );
- if( ms != 0.0 && mt != 0.0 ) {
- REAL d = 1.0 / (ms * mt);
- t *= M_SQRT2;
- REAL ds = t * sqrtf( d * pspec[0].range[2] / pspec[1].range[2] );
- REAL dt = t * sqrtf( d * pspec[1].range[2] / pspec[0].range[2] );
- pspec[0].stepsize = ( ds < pspec[0].range[2] ) ? ds : pspec[0].range[2];
- pspec[0].sidestep[0] = ( msv[0] * pspec[0].range[2] > t ) ? (t / msv[0]) : pspec[0].range[2];
- pspec[0].sidestep[1] = ( msv[1] * pspec[0].range[2] > t ) ? (t / msv[1]) : pspec[0].range[2];
-
- pspec[1].stepsize = ( dt < pspec[1].range[2] ) ? dt : pspec[1].range[2];
- pspec[1].sidestep[0] = ( mtv[0] * pspec[1].range[2] > t ) ? (t / mtv[0]) : pspec[1].range[2];
- pspec[1].sidestep[1] = ( mtv[1] * pspec[1].range[2] > t ) ? (t / mtv[1]) : pspec[1].range[2];
- } else {
- pspec[0].singleStep();
- pspec[1].singleStep();
- }
-*/
- } else {
- pspec[0].singleStep();
- pspec[1].singleStep();
- }
- }
- }
-
-#ifdef DEBUG
- _glu_dprintf( "sidesteps %g %g %g %g, stepsize %g %g\n",
- pspec[0].sidestep[0], pspec[0].sidestep[1],
- pspec[1].sidestep[0], pspec[1].sidestep[1],
- pspec[0].stepsize, pspec[1].stepsize );
-#endif
-
- if( mapdesc->minsavings != N_NOSAVINGSSUBDIVISION ) {
- REAL savings = 1./(pspec[0].stepsize * pspec[1].stepsize) ;
- savings-= (2./( pspec[0].sidestep[0] + pspec[0].sidestep[1] )) *
- (2./( pspec[1].sidestep[0] + pspec[1].sidestep[1] ));
-
- savings *= pspec[0].range[2] * pspec[1].range[2];
- if( savings > mapdesc->minsavings ) {
- pspec[0].needsSubdivision = pspec[1].needsSubdivision = 1;
- }
- }
-
- if( pspec[0].stepsize < pspec[0].minstepsize ) pspec[0].needsSubdivision = 1;
- if( pspec[1].stepsize < pspec[1].minstepsize ) pspec[1].needsSubdivision = 1;
- needsSampling = (needsSampling ? needsSamplingSubdivision() : 0);
-}
-
-void
-Patchspec::singleStep()
-{
- stepsize = sidestep[0] = sidestep[1] = glu_abs(range[2]);
-}
-
-void
-Patchspec::getstepsize( REAL max ) // max is number of samples for entire patch
-{
- stepsize = ( max >= 1.0 ) ? range[2] / max : range[2];
- if (stepsize < 0.0) {
- stepsize = -stepsize;
- }
- sidestep[0] = sidestep[1] = minstepsize = stepsize;
-}
-
-int
-Patch::needsSamplingSubdivision( void )
-{
- return (pspec[0].needsSubdivision || pspec[1].needsSubdivision) ? 1 : 0;
-}
-
-int
-Patch::needsNonSamplingSubdivision( void )
-{
- return notInBbox;
-}
-
-int
-Patch::needsSubdivision( int param )
-{
- return pspec[param].needsSubdivision;
-}
-
-int
-Patch::cullCheck( void )
-{
- if( cullval == CULL_ACCEPT )
- cullval = mapdesc->cullCheck( cpts, pspec[0].order, pspec[0].stride,
- pspec[1].order, pspec[1].stride );
- return cullval;
-}
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * patch.h
- *
- */
-
-#ifndef __glupatch_h_
-#define __glupatch_h_
-
-#include "types.h"
-#include "defines.h"
-
-class Quilt;
-class Mapdesc;
-
-
-struct Pspec {
- REAL range[3];
- REAL sidestep[2];
- REAL stepsize;
- REAL minstepsize;
- int needsSubdivision;
-};
-
-struct Patchspec : public Pspec {
- int order;
- int stride;
- void clamp( REAL );
- void getstepsize( REAL );
- void singleStep( void );
-};
-
-class Patch {
-public:
-friend class Subdivider;
-friend class Quilt;
-friend class Patchlist;
- Patch( Quilt *, REAL*, REAL *, Patch * );
- Patch( Patch &, int, REAL, Patch * );
- void bbox( void );
- void clamp( void );
- void getstepsize( void );
- int cullCheck( void );
- int needsSubdivision( int );
- int needsSamplingSubdivision( void );
- int needsNonSamplingSubdivision( void );
-
- int get_uorder() {return pspec[0].order;}
- int get_vorder() {return pspec[1].order;}
-
-private:
-
- Mapdesc* mapdesc;
- Patch* next;
- int cullval;
- int notInBbox;
- int needsSampling;
- REAL cpts[MAXORDER*MAXORDER*MAXCOORDS]; //culling pts
- REAL spts[MAXORDER*MAXORDER*MAXCOORDS]; //sampling pts
- REAL bpts[MAXORDER*MAXORDER*MAXCOORDS]; //bbox pts
- Patchspec pspec[2];
- void checkBboxConstraint( void );
- REAL bb[2][MAXCOORDS];
-};
-#endif /* __glupatch_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * patchlist.c++
- *
- */
-
-#include <stdio.h>
-#include "glimports.h"
-#include "myassert.h"
-#include "mystdio.h"
-#include "quilt.h"
-#include "patchlist.h"
-#include "patch.h"
-
-Patchlist::Patchlist( Quilt *quilts, REAL *pta, REAL *ptb )
-{
- patch = 0;
- for( Quilt *q = quilts; q; q = q->next )
- patch = new Patch( q, pta, ptb, patch );
- pspec[0].range[0] = pta[0];
- pspec[0].range[1] = ptb[0];
- pspec[0].range[2] = ptb[0] - pta[0];
-
- pspec[1].range[0] = pta[1];
- pspec[1].range[1] = ptb[1];
- pspec[1].range[2] = ptb[1] - pta[1];
-}
-
-Patchlist::Patchlist( Patchlist &upper, int param, REAL value)
-{
- Patchlist &lower = *this;
- patch = 0;
- for( Patch *p = upper.patch; p; p = p->next )
- patch = new Patch( *p, param, value, patch );
-
- if( param == 0 ) {
- lower.pspec[0].range[0] = upper.pspec[0].range[0];
- lower.pspec[0].range[1] = value;
- lower.pspec[0].range[2] = value - upper.pspec[0].range[0];
- upper.pspec[0].range[0] = value;
- upper.pspec[0].range[2] = upper.pspec[0].range[1] - value;
- lower.pspec[1] = upper.pspec[1];
- } else {
- lower.pspec[0] = upper.pspec[0];
- lower.pspec[1].range[0] = upper.pspec[1].range[0];
- lower.pspec[1].range[1] = value;
- lower.pspec[1].range[2] = value - upper.pspec[1].range[0];
- upper.pspec[1].range[0] = value;
- upper.pspec[1].range[2] = upper.pspec[1].range[1] - value;
- }
-}
-
-Patchlist::~Patchlist()
-{
- while( patch ) {
- Patch *p = patch;
- patch = patch->next;
- delete p;
- }
-}
-
-int
-Patchlist::cullCheck( void )
-{
- for( Patch *p = patch; p; p = p->next )
- if( p->cullCheck() == CULL_TRIVIAL_REJECT )
- return CULL_TRIVIAL_REJECT;
- return CULL_ACCEPT;
-}
-
-void
-Patchlist::getRanges(REAL ranges[4])
-{
- ranges[0] = pspec[0].range[0];
- ranges[1] = pspec[0].range[1];
- ranges[2] = pspec[1].range[0];
- ranges[3] = pspec[1].range[1];
-}
-
-void
-Patchlist::getstepsize( void )
-{
- pspec[0].stepsize = pspec[0].range[2];
- pspec[0].sidestep[0] = pspec[0].range[2];
- pspec[0].sidestep[1] = pspec[0].range[2];
-
- pspec[1].stepsize = pspec[1].range[2];
- pspec[1].sidestep[0] = pspec[1].range[2];
- pspec[1].sidestep[1] = pspec[1].range[2];
-
- for( Patch *p = patch; p; p = p->next ) {
- p->getstepsize();
- p->clamp();
- pspec[0].stepsize = ((p->pspec[0].stepsize < pspec[0].stepsize) ? p->pspec[0].stepsize : pspec[0].stepsize);
- pspec[0].sidestep[0] = ((p->pspec[0].sidestep[0] < pspec[0].sidestep[0]) ? p->pspec[0].sidestep[0] : pspec[0].sidestep[0]);
- pspec[0].sidestep[1] = ((p->pspec[0].sidestep[1] < pspec[0].sidestep[1]) ? p->pspec[0].sidestep[1] : pspec[0].sidestep[1]);
- pspec[1].stepsize = ((p->pspec[1].stepsize < pspec[1].stepsize) ? p->pspec[1].stepsize : pspec[1].stepsize);
- pspec[1].sidestep[0] = ((p->pspec[1].sidestep[0] < pspec[1].sidestep[0]) ? p->pspec[1].sidestep[0] : pspec[1].sidestep[0]);
- pspec[1].sidestep[1] = ((p->pspec[1].sidestep[1] < pspec[1].sidestep[1]) ? p->pspec[1].sidestep[1] : pspec[1].sidestep[1]);
- }
-}
-
-void
-Patchlist::bbox( void )
-{
- for( Patch *p = patch; p; p = p->next )
- p->bbox();
-}
-
-int
-Patchlist::needsNonSamplingSubdivision( void )
-{
- notInBbox = 0;
- for( Patch *p = patch; p; p = p->next )
- notInBbox |= p->needsNonSamplingSubdivision();
- return notInBbox;
-}
-
-int
-Patchlist::needsSamplingSubdivision( void )
-{
- pspec[0].needsSubdivision = 0;
- pspec[1].needsSubdivision = 0;
-
- for( Patch *p = patch; p; p = p->next ) {
- pspec[0].needsSubdivision |= p->pspec[0].needsSubdivision;
- pspec[1].needsSubdivision |= p->pspec[0].needsSubdivision;
- }
- return (pspec[0].needsSubdivision || pspec[1].needsSubdivision) ? 1 : 0;
-}
-
-int
-Patchlist::needsSubdivision( int param )
-{
- return pspec[param].needsSubdivision;
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * patchlist.h
- *
- */
-
-#ifndef __glupatchlist_h_
-#define __glupatchlist_h_
-
-#include "types.h"
-#include "defines.h"
-#include "patch.h"
-
-class Quilt;
-
-class Patchlist {
-friend class Subdivider;
-public:
- Patchlist( Quilt *, REAL *, REAL * );
- Patchlist( Patchlist &, int , REAL );
- ~Patchlist();
- void bbox();
- int cullCheck( void );
- void getstepsize( void );
- int needsNonSamplingSubdivision( void );
- int needsSamplingSubdivision( void );
- int needsSubdivision( int );
- REAL getStepsize( int );
- void getRanges(REAL ranges[4]);
-
- int get_uorder();
- int get_vorder();
-private:
- Patch *patch;
- int notInBbox;
- int needsSampling;
- Pspec pspec[2];
-};
-
-inline REAL
-Patchlist::getStepsize( int param )
-{
- return pspec[param].stepsize;
-}
-
-inline int
-Patchlist::get_uorder()
-{
- return patch->get_uorder();
-
-}
-
-inline int
- Patchlist::get_vorder()
-{
- return patch->get_vorder();
-}
-
-
-
-
-
-#endif /* __glupatchlist_h_ */
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * pwlarc.h
- *
- */
-
-#ifndef __glupwlarc_h_
-#define __glupwlarc_h_
-
-#include "myassert.h"
-#include "nurbsconsts.h"
-
-class TrimVertex;
-
-class PwlArc : public PooledObj { /* a piecewise-linear arc */
-public:
- TrimVertex * pts; /* sample points */
- int npts; /* number of sample points */
- long type; /* curve type */
- inline PwlArc( void );
- inline PwlArc( int, TrimVertex * );
- inline PwlArc( int, TrimVertex *, long );
-};
-
-inline
-PwlArc::PwlArc( void )
-{
- type = N_P2D;
- pts = 0;
- npts = -1;
-}
-
-inline
-PwlArc::PwlArc( int _npts, TrimVertex *_pts )
-{
- pts = _pts;
- npts = _npts;
- type = N_P2D;
-}
-
-inline
-PwlArc::PwlArc( int _npts, TrimVertex *_pts, long _type )
-{
- pts = _pts;
- npts = _npts;
- type = _type;
-}
-
-#endif /* __glupwlarc_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * quilt.c++
- *
- */
-
-#include "glimports.h"
-#include "mystdio.h"
-#include "myassert.h"
-#include "quilt.h"
-#include "backend.h"
-#include "mapdesc.h"
-#include "flist.h"
-#include "patchlist.h"
-#include "simplemath.h" //min()
-
-/* local preprocessor definitions */
-#define DEF_PATCH_STEPSIZE .4
-#define fsizeof(x) (sizeof(x)/sizeof(REAL))
-
-
-Quilt::Quilt( Mapdesc *_mapdesc )
-{
- mapdesc = _mapdesc;
-}
-
-void
-Quilt::deleteMe( Pool& p )
-{
- for( Quiltspec *q=qspec; q != eqspec; q++ ) {
-#if 1
- if( q->breakpoints) delete[] q->breakpoints; q->breakpoints = 0;
-#else
- if( q->breakpoints) {
- delete[] q->breakpoints;
- q->breakpoints = 0;
-printf("in here\n");
- }
-#endif
- }
- if( cpts ) delete[] cpts;
- cpts = 0;
- PooledObj::deleteMe( p );
-}
-
-void
-Quilt::show( void )
-{
-#ifndef NDEBUG
- int nc = mapdesc->getNcoords();
- REAL *ps = cpts;
- ps += qspec[0].offset;
- ps += qspec[1].offset;
- for( int i=0; i!= qspec[0].order * qspec[0].width; i++ ) {
- for( int j = 0; j!= qspec[1].order * qspec[1].width; j++ ) {
- for( int k=0; k < nc; k++ )
- _glu_dprintf( "%g ", ps[i*qspec[0].stride + j*qspec[1].stride + k] );
- _glu_dprintf( "\n" );
- }
- _glu_dprintf( "\n" );
- }
- _glu_dprintf( "\n" );
-#endif
-}
-
-/*--------------------------------------------------------------------------
- * Quilt::select - find which map in each quilt contains the points
- * pta and ptb with pta[i] < ptb[i]
- *--------------------------------------------------------------------------
- */
-
-void
-Quilt::select( REAL *pta, REAL *ptb )
-{
- int dim = eqspec - qspec;
- int i, j;
- for( i=0; i<dim; i++) {
- for( j=qspec[i].width-1; j>=0; j-- )
- if( (qspec[i].breakpoints[j] <= pta[i] ) &&
- (ptb[i] <= qspec[i].breakpoints[j+1] ) )
- break;
- assert( j != -1 );
- qspec[i].index = j;
- }
-}
-
-void
-Quilt::download( Backend &backend )
-{
- if( getDimension() == 2 ) {
- REAL *ps = cpts;
- ps += qspec[0].offset;
- ps += qspec[1].offset;
- ps += qspec[0].index * qspec[0].order * qspec[0].stride;
- ps += qspec[1].index * qspec[1].order * qspec[1].stride;
- backend.surfpts( mapdesc->getType(), ps,
- qspec[0].stride,
- qspec[1].stride,
- qspec[0].order,
- qspec[1].order,
- qspec[0].breakpoints[qspec[0].index],
- qspec[0].breakpoints[qspec[0].index+1],
- qspec[1].breakpoints[qspec[1].index],
- qspec[1].breakpoints[qspec[1].index+1] );
- } else {
- REAL *ps = cpts;
- ps += qspec[0].offset;
- ps += qspec[0].index * qspec[0].order * qspec[0].stride;
- backend.curvpts( mapdesc->getType(), ps,
- qspec[0].stride,
- qspec[0].order,
- qspec[0].breakpoints[qspec[0].index],
- qspec[0].breakpoints[qspec[0].index+1] );
- }
-}
-
-/*--------------------------------------------------------------------------
- * Quilt::downloadAll - download each map that contains the current patch
- *--------------------------------------------------------------------------
- */
-
-void
-Quilt::downloadAll( REAL *pta, REAL *ptb, Backend &backend )
-{
- for( Quilt *m = this; m; m=m->next ) {
- m->select( pta, ptb );
- m->download( backend );
- }
-}
-
-/*--------------------------------------------------------------------------
- * Quilt::isCulled - determine if an entire quilt is trivially rejected.
- *--------------------------------------------------------------------------
- */
-
-int
-Quilt::isCulled( void )
-{
- if( mapdesc->isCulling() )
- return mapdesc->xformAndCullCheck( cpts + qspec[0].offset + qspec[1].offset,
- qspec[0].order * qspec[0].width, qspec[0].stride,
- qspec[1].order * qspec[1].width, qspec[1].stride );
- else
- return CULL_ACCEPT;
-}
-
-/*---------------------------------------------------------------------------
- * Quilt::getRange - retrieve the valid paramater range of a set of quilts
- *---------------------------------------------------------------------------
- */
-void
-Quilt::getRange( REAL *from, REAL *to, Flist& slist, Flist &tlist )
-{
- getRange( from, to, 0, slist );
- getRange( from, to, 1, tlist );
-}
-
-/*---------------------------------------------------------------------------
- * Quilt::getRange - retrieve the valid paramater range of a set of quilts
- *---------------------------------------------------------------------------
- */
-void
-Quilt::getRange( REAL *from, REAL *to, int i, Flist &list )
-{
- Quilt *maps = this;
- from[i] = maps->qspec[i].breakpoints[0];
- to[i] = maps->qspec[i].breakpoints[maps->qspec[i].width];
- int maxpts = 0;
- Quilt_ptr m;
- for( m=maps; m; m=m->next ) {
- if( m->qspec[i].breakpoints[0] > from[i] )
- from[i] = m->qspec[i].breakpoints[0];
- if( m->qspec[i].breakpoints[m->qspec[i].width] < to[i] )
- to[i] = m->qspec[i].breakpoints[m->qspec[i].width];
- maxpts += m->qspec[i].width + 1;
- }
-
- list.grow( maxpts );
-
- for( m=maps; m; m=m->next )
- for( int j=0; j<=m->qspec[i].width; j++ ) {
- list.add( m->qspec[i].breakpoints[j] );
- }
-
- list.filter( );
- list.taper( from[i], to[i] );
-}
-
-void
-Quilt::getRange( REAL *from, REAL *to, Flist& slist )
-{
- getRange( from, to, 0, slist );
-}
-
-void
-Quilt::findRates( Flist& slist, Flist& tlist, REAL rate[2] )
-{
- findSampleRates( slist, tlist );
- rate[0] = qspec[0].step_size;
- rate[1] = qspec[1].step_size;
-
- for( Quilt *q = next; q; q = q->next ) {
- q->findSampleRates( slist, tlist );
- if( q->qspec[0].step_size < rate[0] )
- rate[0] = q->qspec[0].step_size;
- if( q->qspec[1].step_size < rate[1] )
- rate[1] = q->qspec[1].step_size;
- }
-}
-
-void
-Quilt::findSampleRates( Flist& slist, Flist& tlist )
-{
- qspec[0].step_size = DEF_PATCH_STEPSIZE *
- (qspec[0].breakpoints[qspec[0].width] - qspec[0].breakpoints[0]);
- qspec[1].step_size = DEF_PATCH_STEPSIZE *
- (qspec[1].breakpoints[qspec[1].width] - qspec[1].breakpoints[0]);
-
- for( int i = slist.start; i < slist.end-1; i++ ) {
- for( int j = tlist.start; j < tlist.end-1; j++ ) {
-
- REAL pta[2], ptb[2];
- pta[0] = slist.pts[i];
- ptb[0] = slist.pts[i+1];
- pta[1] = tlist.pts[j];
- ptb[1] = tlist.pts[j+1];
- Patchlist patchlist( this, pta, ptb );
- patchlist.getstepsize();
-
- {
- float edge_len_s = min(glu_abs(ptb[0]-pta[0]),1.0);
- float edge_len_t = min(glu_abs(ptb[1]-pta[1]),1.0);
-
- if( patchlist.getStepsize(0)/edge_len_s < qspec[0].step_size )
- qspec[0].step_size = patchlist.getStepsize(0)/edge_len_s;
- if( patchlist.getStepsize(1)/edge_len_t < qspec[1].step_size )
- qspec[1].step_size = patchlist.getStepsize(1)/edge_len_t;
- }
- }
- }
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * quilt.h
- *
- */
-
-#ifndef __gluquilt_h_
-#define __gluquilt_h_
-
-#include "defines.h"
-#include "bufpool.h"
-#include "types.h"
-
-class Backend;
-class Mapdesc;
-class Flist;
-struct Knotvector;
-
-/* constants for memory allocation of NURBS to Bezier conversion */
-#define MAXDIM 2
-
-struct Quiltspec { /* a specification for a dimension of a quilt */
- int stride; /* words between points */
- int width; /* number of segments */
- int offset; /* words to first point */
- int order; /* order */
- int index; /* current segment number */
- int bdry[2]; /* boundary edge flag */
- REAL step_size;
- Knot * breakpoints;
-};
-
-typedef Quiltspec *Quiltspec_ptr;
-
-class Quilt : public PooledObj { /* an array of bezier patches */
-public:
- Quilt( Mapdesc * );
- Mapdesc * mapdesc; /* map descriptor */
- REAL * cpts; /* control points */
- Quiltspec qspec[MAXDIM]; /* the dimensional data */
- Quiltspec_ptr eqspec; /* qspec trailer */
- Quilt *next; /* next quilt in linked list */
-
-public:
- void deleteMe( Pool& );
- void toBezier( Knotvector &, INREAL *, long );
- void toBezier( Knotvector &, Knotvector &, INREAL *, long );
- void select( REAL *, REAL * );
- int getDimension( void ) { return eqspec - qspec; }
- void download( Backend & );
- void downloadAll( REAL *, REAL *, Backend & );
- int isCulled( void );
- void getRange( REAL *, REAL *, Flist&, Flist & );
- void getRange( REAL *, REAL *, int, Flist & );
- void getRange( REAL *, REAL *, Flist& );
- void findRates( Flist& slist, Flist& tlist, REAL[2] );
- void findSampleRates( Flist& slist, Flist& tlist );
- void show();
-};
-
-typedef class Quilt *Quilt_ptr;
-
-#endif /* __gluquilt_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * reader.c++
- *
- */
-
-#include <stdio.h>
-#include "glimports.h"
-#include "nurbsconsts.h"
-#include "reader.h"
-#include "trimvertex.h"
-#include "simplemath.h"
-
-//when read a pwlCurve, if two consecutive points are the same, then
-//eliminate one of them. This makes the tessellator more robust. The spec
-//assumes the application makes sure there are no redundant points.
-//but in Inspector, the trim curves seem to have redundant points a lot.
-//I guess other similar users may have the same problem.
-
-#define ELIMINATE_REDUNDANT_POINTS
-
-#ifdef ELIMINATE_REDUNDANT_POINTS
-#define equal(x,y) ( glu_abs(x-y) <= 0.00001)
-#endif
-
-#ifdef ELIMINATE_REDUNDANT_POINTS
-O_pwlcurve::O_pwlcurve( long _type, long count, INREAL *array, long byte_stride, TrimVertex *trimpts )
-{
- next = 0;
- used = 0;
- owner = 0;
- pts = trimpts;
- npts = (int) count;
- save = 0;
- int i;
-
- /* copy user data into internal trimming data structures */
- switch( _type ) {
- case N_P2D: {
- TrimVertex *v = pts;
- TrimVertex *prev = NULL;
- int num = 0;
- int doit;
- for(i=0; i<count; i++) {
- doit = 1;
- if(prev != NULL)
- {
- if(equal(prev->param[0], array[0]) && equal(prev->param[1], array[1]))
- {
- doit = 0;
- }
- }
-
- if(doit)
- {
- v->param[0] = (REAL) array[0];
- v->param[1] = (REAL) array[1];
- prev = v;
- v++;
- num++;
- }
- array = (INREAL *) (((char *) array) + byte_stride);
- }
- npts = num;
- break;
- }
- case N_P2DR: {
- TrimVertex *v = pts;
- for( TrimVertex *lastv = v + count; v != lastv; v++ ) {
- v->param[0] = (REAL) array[0] / (REAL) array[2];
- v->param[1] = (REAL) array[1] / (REAL) array[2];
- array = (INREAL *) (((char *) array) + byte_stride);
- }
- break;
- }
- }
-}
-#else
-O_pwlcurve::O_pwlcurve( long _type, long count, INREAL *array, long byte_stride, TrimVertex *trimpts )
-{
- next = 0;
- used = 0;
- owner = 0;
- pts = trimpts;
- npts = (int) count;
- save = 0;
-
- /* copy user data into internal trimming data structures */
- switch( _type ) {
- case N_P2D: {
- TrimVertex *v = pts;
- for( TrimVertex *lastv = v + count; v != lastv; v++ ) {
- v->param[0] = (REAL) array[0];
- v->param[1] = (REAL) array[1];
- array = (INREAL *) (((char *) array) + byte_stride);
- }
- break;
- }
- case N_P2DR: {
- TrimVertex *v = pts;
- for( TrimVertex *lastv = v + count; v != lastv; v++ ) {
- v->param[0] = (REAL) array[0] / (REAL) array[2];
- v->param[1] = (REAL) array[1] / (REAL) array[2];
- array = (INREAL *) (((char *) array) + byte_stride);
- }
- break;
- }
- }
-}
-#endif
-
-
-
-
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * reader.h
- *
- */
-
-#ifndef __glureader_h_
-#define __glureader_h_
-
-#include "bufpool.h"
-#include "types.h"
-
-enum Curvetype { ct_nurbscurve, ct_pwlcurve, ct_none };
-
-struct Property;
-struct O_surface;
-struct O_nurbssurface;
-struct O_trim;
-class O_pwlcurve;
-struct O_nurbscurve;
-struct O_curve;
-class Quilt;
-class TrimVertex;
-
-
-struct O_curve : public PooledObj {
- union {
- O_nurbscurve *o_nurbscurve;
- O_pwlcurve *o_pwlcurve;
- } curve;
- Curvetype curvetype; /* arc type: pwl or nurbs */
- O_curve * next; /* next arc in loop */
- O_surface * owner; /* owning surface */
- int used; /* curve called in cur surf */
- int save; /* 1 if in display list */
- long nuid;
- O_curve() { next = 0; used = 0; owner = 0;
- curve.o_pwlcurve = 0; curvetype = ct_none; save = 0; nuid = 0; }
- };
-
-struct O_nurbscurve : public PooledObj {
- Quilt *bezier_curves; /* array of bezier curves */
- long type; /* range descriptor */
- REAL tesselation; /* tesselation tolerance */
- int method; /* tesselation method */
- O_nurbscurve * next; /* next curve in list */
- int used; /* curve called in cur surf */
- int save; /* 1 if in display list */
- O_curve * owner; /* owning curve */
- O_nurbscurve( long _type )
- { bezier_curves = 0; type = _type; tesselation = 0; method = 0; next = 0; used = 0; save = 0; owner = 0; }
- };
-
-class O_pwlcurve : public PooledObj {
-public:
- TrimVertex *pts; /* array of trim vertices */
- int npts; /* number of trim vertices */
- O_pwlcurve * next; /* next curve in list */
- int used; /* curve called in cur surf */
- int save; /* 1 if in display list */
- O_curve * owner; /* owning curve */
- O_pwlcurve( long, long, INREAL *, long, TrimVertex * );
- };
-
-struct O_trim : public PooledObj {
- O_curve *o_curve; /* closed trim loop */
- O_trim * next; /* next loop along trim */
- int save; /* 1 if in display list */
- O_trim() { next = 0; o_curve = 0; save = 0; }
- };
-
-struct O_nurbssurface : public PooledObj {
- Quilt * bezier_patches;/* array of bezier patches */
- long type; /* range descriptor */
- O_surface * owner; /* owning surface */
- O_nurbssurface * next; /* next surface in chain */
- int save; /* 1 if in display list */
- int used; /* 1 if prev called in block */
- O_nurbssurface( long _type )
- { bezier_patches = 0; type = _type; owner = 0; next = 0; save = 0; used = 0; }
- };
-
-struct O_surface : public PooledObj {
- O_nurbssurface * o_nurbssurface; /* linked list of surfaces */
- O_trim * o_trim; /* list of trim loops */
- int save; /* 1 if in display list */
- long nuid;
- O_surface() { o_trim = 0; o_nurbssurface = 0; save = 0; nuid = 0; }
- };
-
-struct Property : public PooledObj {
- long type;
- long tag;
- REAL value;
- int save; /* 1 if in display list */
- Property( long _type, long _tag, INREAL _value )
- { type = _type; tag = _tag; value = (REAL) _value; save = 0; }
- Property( long _tag, INREAL _value )
- { type = 0; tag = _tag; value = (REAL) _value; save = 0; }
- };
-
-class NurbsTessellator;
-#endif /* __glureader_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * renderhints.c++
- *
- */
-
-#include "glimports.h"
-#include "mystdio.h"
-#include "renderhints.h"
-#include "nurbsconsts.h"
-
-
-/*--------------------------------------------------------------------------
- * Renderhints::Renderhints - set all window specific options
- *--------------------------------------------------------------------------
- */
-Renderhints::Renderhints()
-{
- display_method = N_FILL;
- errorchecking = N_MSG;
- subdivisions = 6.0;
- tmp1 = 0.0;
- displaydomain = 0;
- maxsubdivisions = (int) subdivisions;
- wiretris = 0;
- wirequads = 0;
-}
-
-void
-Renderhints::init( void )
-{
- maxsubdivisions = (int) subdivisions;
- if( maxsubdivisions < 0 ) maxsubdivisions = 0;
-
-
- if( display_method == N_FILL ) {
- wiretris = 0;
- wirequads = 0;
- } else if( display_method == N_OUTLINE_TRI ) {
- wiretris = 1;
- wirequads = 0;
- } else if( display_method == N_OUTLINE_QUAD ) {
- wiretris = 0;
- wirequads = 1;
- } else {
- wiretris = 1;
- wirequads = 1;
- }
-}
-
-int
-Renderhints::isProperty( long property )
-{
- switch ( property ) {
- case N_DISPLAY:
- case N_ERRORCHECKING:
- case N_SUBDIVISIONS:
- case N_TMP1:
- return 1;
- default:
- return 0;
- }
-}
-
-REAL
-Renderhints::getProperty( long property )
-{
- switch ( property ) {
- case N_DISPLAY:
- return display_method;
- case N_ERRORCHECKING:
- return errorchecking;
- case N_SUBDIVISIONS:
- return subdivisions;
- case N_TMP1:
- return tmp1;
- default:
- abort();
- return -1; //not necessary, needed to shut up compiler
- }
-}
-
-void
-Renderhints::setProperty( long property, REAL value )
-{
- switch ( property ) {
- case N_DISPLAY:
- display_method = value;
- break;
- case N_ERRORCHECKING:
- errorchecking = value;
- break;
- case N_SUBDIVISIONS:
- subdivisions = value;
- break;
- case N_TMP1: /* unused */
- tmp1 = value;
- break;
- default:
- abort();
- break;
- }
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * renderhints.h
- *
- */
-
-#ifndef __glurenderhints_h_
-#define __glurenderhints_h_
-
-#include "types.h"
-
-class Renderhints {
-public:
- Renderhints( void );
- void init( void );
- int isProperty( long );
- REAL getProperty( long );
- void setProperty( long, REAL );
-
- REAL display_method; /* display mode */
- REAL errorchecking; /* activate error checking */
- REAL subdivisions; /* maximum number of subdivisions per patch */
- REAL tmp1; /* unused */
-
- int displaydomain;
- int maxsubdivisions;
- int wiretris;
- int wirequads;
-};
-
-#endif /* __glurenderhints_h_ */
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * simplemath.h
- *
- */
-
-#ifndef __glusimplemath_h_
-#define __glusimplemath_h_
-
-/* simple inline routines */
-
-#include "types.h"
-
-inline int
-max( int x, int y ) { return ( x < y ) ? y : x; }
-
-inline REAL
-min( REAL x, REAL y ) { return ( x > y ) ? y : x; }
-
-inline REAL
-glu_abs( REAL x ) { return ( x < 0.0 ) ? -x : x; }
-
-#endif /* __glusimplemath_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * slicer.c++
- *
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-#include "glimports.h"
-#include "mystdio.h"
-#include "myassert.h"
-#include "bufpool.h"
-#include "slicer.h"
-#include "backend.h"
-#include "arc.h"
-#include "gridtrimvertex.h"
-#include "simplemath.h"
-#include "trimvertex.h"
-#include "varray.h"
-
-#include "polyUtil.h" //for area()
-
-//static int count=0;
-
-/*USE_OPTTT is initiated in trimvertex.h*/
-
-#ifdef USE_OPTTT
- #include <GL/gl.h>
-#endif
-
-//#define USE_READ_FLAG //whether to use new or old tesselator
- //if defined, it reads "flagFile",
- // if the number is 1, then use new tess
- // otherwise, use the old tess.
- //if not defined, then use new tess.
-#ifdef USE_READ_FLAG
-static Int read_flag(char* name);
-Int newtess_flag = read_flag("flagFile");
-#endif
-
-//#define COUNT_TRIANGLES
-#ifdef COUNT_TRIANGLES
-Int num_triangles = 0;
-Int num_quads = 0;
-#endif
-
-#define max(a,b) ((a>b)? a:b)
-#define ZERO 0.00001 /*determing whether a loop is a rectngle or not*/
-#define equalRect(a,b) ((glu_abs(a-b) <= ZERO)? 1:0) //only used in tessellating a rectangle
-
-#if 0 // UNUSED
-static Int is_Convex(Arc_ptr loop)
-{
- if(area(loop->tail(), loop->head(), loop->next->head()) <0 )
- return 0;
- for(Arc_ptr jarc = loop->next; jarc != loop; jarc = jarc->next)
- {
- if(area(jarc->tail(), jarc->head(), jarc->next->head()) < 0)
- return 0;
- }
- return 1;
-}
-#endif
-
-/******triangulate a monotone polygon**************/
-#include "monoTriangulation.h"
-#if 0 // UNUSED
-static int is_U_monotone(Arc_ptr loop)
-{
- int n_changes=0;
- int prev_sign;
- int cur_sign;
- Arc_ptr temp;
-
- cur_sign = compV2InX(loop->head(), loop->tail());
-
- n_changes = (compV2InX(loop->prev->head(), loop->prev->tail())
- != cur_sign);
-
- for(temp=loop->next; temp != loop; temp = temp->next)
- {
- prev_sign = cur_sign;
- cur_sign = compV2InX(temp->head(), temp->tail());
- if(cur_sign != prev_sign)
- {
-#ifdef DEBUG
- printf("***change signe\n");
-#endif
- n_changes++;
- }
- }
- if(n_changes == 2) return 1;
- else
- return 0;
-}
-#endif
-
-inline int compInY(REAL a[2], REAL b[2])
-{
- if(a[1] < b[1])
- return -1;
- else if (a[1] > b[1])
- return 1;
- else if(a[0] > b[0])
- return 1;
- else return -1;
-}
-
-void monoTriangulationLoop(Arc_ptr loop, Backend& backend, primStream* pStream)
-{
- int i;
- //find the top, bottom, increasing and decreasing chain
- //then call monoTrianulation
- Arc_ptr jarc, temp;
- Arc_ptr top;
- Arc_ptr bot;
- top = bot = loop;
- if(compInY(loop->tail(), loop->prev->tail()) < 0)
- {
- //first find bot
- for(temp = loop->next; temp != loop; temp = temp->next)
- {
- if(compInY(temp->tail(), temp->prev->tail()) > 0)
- break;
- }
- bot = temp->prev;
- //then find top
- for(temp=loop->prev; temp != loop; temp = temp->prev)
- {
- if(compInY(temp->tail(), temp->prev->tail()) > 0)
- break;
- }
- top = temp;
- }
- else //loop > loop->prev
- {
- for(temp=loop->next; temp != loop; temp = temp->next)
- {
- if(compInY(temp->tail(), temp->prev->tail()) < 0)
- break;
- }
- top = temp->prev;
- for(temp=loop->prev; temp != loop; temp = temp->prev)
- {
- if(compInY(temp->tail(), temp->prev->tail()) < 0)
- break;
- }
- bot = temp;
- }
- //creat increase and decrease chains
- vertexArray inc_chain(50); //this is a dynamci array
- for(i=1; i<=top->pwlArc->npts-2; i++)
- {
- //the first vertex is the top which doesn't below to inc_chain
- inc_chain.appendVertex(top->pwlArc->pts[i].param);
- }
- for(jarc=top->next; jarc != bot; jarc = jarc->next)
- {
- for(i=0; i<=jarc->pwlArc->npts-2; i++)
- {
- inc_chain.appendVertex(jarc->pwlArc->pts[i].param);
- }
-
- }
- vertexArray dec_chain(50);
- for(jarc = top->prev; jarc != bot; jarc = jarc->prev)
- {
- for(i=jarc->pwlArc->npts-2; i>=0; i--)
- {
- dec_chain.appendVertex(jarc->pwlArc->pts[i].param);
- }
- }
- for(i=bot->pwlArc->npts-2; i>=1; i--)
- {
- dec_chain.appendVertex(jarc->pwlArc->pts[i].param);
- }
-
- monoTriangulationRec(top->tail(), bot->tail(), &inc_chain, 0,
- &dec_chain, 0, &backend);
-
-}
-
-/********tesselate a rectanlge (OPTIMIZATION**************/
-static void triangulateRectGen(Arc_ptr loop, int n_ulines, int n_vlines, Backend& backend);
-
-static Int is_rect(Arc_ptr loop)
-{
- Int nlines =1;
- for(Arc_ptr jarc = loop->next; jarc != loop; jarc = jarc->next)
- {
- nlines++;
- if(nlines == 5)
- break;
- }
- if(nlines != 4)
- return 0;
-
-
-/*
-printf("here1\n");
-printf("loop->tail=(%f,%f)\n", loop->tail()[0], loop->tail()[1]);
-printf("loop->head=(%f,%f)\n", loop->head()[0], loop->head()[1]);
-printf("loop->next->tail=(%f,%f)\n", loop->next->tail()[0], loop->next->tail()[1]);
-printf("loop->next->head=(%f,%f)\n", loop->next->head()[0], loop->next->head()[1]);
-if(fglu_abs(loop->tail()[0] - loop->head()[0])<0.000001)
- printf("equal 1\n");
-if(loop->next->tail()[1] == loop->next->head()[1])
- printf("equal 2\n");
-*/
-
- if( (glu_abs(loop->tail()[0] - loop->head()[0])<=ZERO) &&
- (glu_abs(loop->next->tail()[1] - loop->next->head()[1])<=ZERO) &&
- (glu_abs(loop->prev->tail()[1] - loop->prev->head()[1])<=ZERO) &&
- (glu_abs(loop->prev->prev->tail()[0] - loop->prev->prev->head()[0])<=ZERO)
- )
- return 1;
- else if
- ( (glu_abs(loop->tail()[1] - loop->head()[1]) <= ZERO) &&
- (glu_abs(loop->next->tail()[0] - loop->next->head()[0]) <= ZERO) &&
- (glu_abs(loop->prev->tail()[0] - loop->prev->head()[0]) <= ZERO) &&
- (glu_abs(loop->prev->prev->tail()[1] - loop->prev->prev->head()[1]) <= ZERO)
- )
- return 1;
- else
- return 0;
-}
-
-
-//a line with the same u for opt
-#ifdef USE_OPTTT
-static void evalLineNOGE_BU(TrimVertex *verts, int n, Backend& backend)
-{
- int i;
- backend.preEvaluateBU(verts[0].param[0]);
- for(i=0; i<n; i++)
- backend.tmeshvertNOGE_BU(&verts[i]);
-}
-#endif
-
-//a line with the same v for opt
-#ifdef USE_OPTTT
-static void evalLineNOGE_BV(TrimVertex *verts, int n, Backend& backend)
-{
- int i;
- backend.preEvaluateBV(verts[0].param[1]);
-
- for(i=0; i<n; i++)
- backend.tmeshvertNOGE_BV(&verts[i]);
-}
-#endif
-
-#ifdef USE_OPTTT
-static void evalLineNOGE(TrimVertex *verts, int n, Backend& backend)
-{
-
- if(verts[0].param[0] == verts[n-1].param[0]) //all u;s are equal
- evalLineNOGE_BU(verts, n, backend);
- else if(verts[0].param[1] == verts[n-1].param[1]) //all v's are equal
- evalLineNOGE_BV(verts, n, backend);
- else
- {
- int i;
- for(i=0; i<n; i++)
- backend.tmeshvertNOGE(&verts[i]);
- }
-}
-#endif
-
-inline void OPT_OUTVERT(TrimVertex& vv, Backend& backend)
-{
-
-#ifdef USE_OPTTT
- glNormal3fv(vv.cache_normal);
- glVertex3fv(vv.cache_point);
-#else
-
- backend.tmeshvert(&vv);
-
-#endif
-
-}
-
-static void triangulateRectAux(PwlArc* top, PwlArc* bot, PwlArc* left, PwlArc* right, Backend& backend);
-
-static void triangulateRect(Arc_ptr loop, Backend& backend, int TB_or_LR, int ulinear, int vlinear)
-{
- //we know the loop is a rectangle, but not sure which is top
- Arc_ptr top, bot, left, right;
- if(loop->tail()[1] == loop->head()[1])
- {
- if(loop->tail()[1] > loop->prev->prev->tail()[1])
- {
-
- top = loop;
- }
- else{
-
- top = loop->prev->prev;
- }
- }
- else
- {
- if(loop->tail()[0] > loop->prev->prev->tail()[0])
- {
- //loop is the right arc
-
- top = loop->next;
- }
- else
- {
-
- top = loop->prev;
- }
- }
- left = top->next;
- bot = left->next;
- right= bot->next;
-
- //if u, v are both nonlinear, then if the
- //boundary is tessellated dense, we also
- //sample the inside to get a better tesslletant.
- if( (!ulinear) && (!vlinear))
- {
- int nu = top->pwlArc->npts;
- if(nu < bot->pwlArc->npts)
- nu = bot->pwlArc->npts;
- int nv = left->pwlArc->npts;
- if(nv < right->pwlArc->npts)
- nv = right->pwlArc->npts;
-/*
- if(nu > 2 && nv > 2)
- {
- triangulateRectGen(top, nu-2, nv-2, backend);
- return;
- }
-*/
- }
-
- if(TB_or_LR == 1)
- triangulateRectAux(top->pwlArc, bot->pwlArc, left->pwlArc, right->pwlArc, backend);
- else if(TB_or_LR == -1)
- triangulateRectAux(left->pwlArc, right->pwlArc, bot->pwlArc, top->pwlArc, backend);
- else
- {
- Int maxPointsTB = top->pwlArc->npts + bot->pwlArc->npts;
- Int maxPointsLR = left->pwlArc->npts + right->pwlArc->npts;
-
- if(maxPointsTB < maxPointsLR)
- triangulateRectAux(left->pwlArc, right->pwlArc, bot->pwlArc, top->pwlArc, backend);
- else
- triangulateRectAux(top->pwlArc, bot->pwlArc, left->pwlArc, right->pwlArc, backend);
- }
-}
-
-static void triangulateRectAux(PwlArc* top, PwlArc* bot, PwlArc* left, PwlArc* right, Backend& backend)
-{ //if(maxPointsTB >= maxPointsLR)
- {
-
- Int d, topd_left, topd_right, botd_left, botd_right, i,j;
- d = left->npts /2;
-
-#ifdef USE_OPTTT
- evalLineNOGE(top->pts, top->npts, backend);
- evalLineNOGE(bot->pts, bot->npts, backend);
- evalLineNOGE(left->pts, left->npts, backend);
- evalLineNOGE(right->pts, right->npts, backend);
-#endif
-
- if(top->npts == 2) {
- backend.bgntfan();
- OPT_OUTVERT(top->pts[0], backend);//the root
- for(i=0; i<left->npts; i++){
- OPT_OUTVERT(left->pts[i], backend);
- }
- for(i=1; i<= bot->npts-2; i++){
- OPT_OUTVERT(bot->pts[i], backend);
- }
- backend.endtfan();
-
- backend.bgntfan();
- OPT_OUTVERT(bot->pts[bot->npts-2], backend);
- for(i=0; i<right->npts; i++){
- OPT_OUTVERT(right->pts[i], backend);
- }
- backend.endtfan();
- }
- else if(bot->npts == 2) {
- backend.bgntfan();
- OPT_OUTVERT(bot->pts[0], backend);//the root
- for(i=0; i<right->npts; i++){
- OPT_OUTVERT(right->pts[i], backend);
- }
- for(i=1; i<= top->npts-2; i++){
- OPT_OUTVERT(top->pts[i], backend);
- }
- backend.endtfan();
-
- backend.bgntfan();
- OPT_OUTVERT(top->pts[top->npts-2], backend);
- for(i=0; i<left->npts; i++){
- OPT_OUTVERT(left->pts[i], backend);
- }
- backend.endtfan();
- }
- else { //both top and bot have >=3 points
-
- backend.bgntfan();
-
- OPT_OUTVERT(top->pts[top->npts-2], backend);
-
- for(i=0; i<=d; i++)
- {
- OPT_OUTVERT(left->pts[i], backend);
- }
- backend.endtfan();
-
- backend.bgntfan();
-
- OPT_OUTVERT(bot->pts[1], backend);
-
- OPT_OUTVERT(top->pts[top->npts-2], backend);
-
- for(i=d; i< left->npts; i++)
- {
- OPT_OUTVERT(left->pts[i], backend);
- }
- backend.endtfan();
-
- d = right->npts/2;
- //output only when d<right->npts-1 and
- //
- if(d<right->npts-1)
- {
- backend.bgntfan();
- // backend.tmeshvert(& top->pts[1]);
- OPT_OUTVERT(top->pts[1], backend);
- for(i=d; i< right->npts; i++)
- {
- // backend.tmeshvert(& right->pts[i]);
-
- OPT_OUTVERT(right->pts[i], backend);
-
- }
- backend.endtfan();
- }
-
- backend.bgntfan();
- // backend.tmeshvert(& bot->pts[bot->npts-2]);
- OPT_OUTVERT( bot->pts[bot->npts-2], backend);
- for(i=0; i<=d; i++)
- {
- // backend.tmeshvert(& right->pts[i]);
- OPT_OUTVERT(right->pts[i], backend);
-
- }
-
- // backend.tmeshvert(& top->pts[1]);
- OPT_OUTVERT(top->pts[1], backend);
-
- backend.endtfan();
-
-
- topd_left = top->npts-2;
- topd_right = 1; //topd_left>= topd_right
-
- botd_left = 1;
- botd_right = bot->npts-2; //botd_left<= bot_dright
-
-
- if(top->npts < bot->npts)
- {
- int delta=bot->npts - top->npts;
- int u = delta/2;
- botd_left = 1+ u;
- botd_right = bot->npts-2-( delta-u);
-
- if(botd_left >1)
- {
- backend.bgntfan();
- // backend.tmeshvert(& top->pts[top->npts-2]);
- OPT_OUTVERT(top->pts[top->npts-2], backend);
- for(i=1; i<= botd_left; i++)
- {
- // backend.tmeshvert(& bot->pts[i]);
- OPT_OUTVERT(bot->pts[i] , backend);
- }
- backend.endtfan();
- }
- if(botd_right < bot->npts-2)
- {
- backend.bgntfan();
- OPT_OUTVERT(top->pts[1], backend);
- for(i=botd_right; i<= bot->npts-2; i++)
- OPT_OUTVERT(bot->pts[i], backend);
- backend.endtfan();
- }
- }
- else if(top->npts> bot->npts)
- {
- int delta=top->npts-bot->npts;
- int u = delta/2;
- topd_left = top->npts-2 - u;
- topd_right = 1+delta-u;
-
- if(topd_left < top->npts-2)
- {
- backend.bgntfan();
- // backend.tmeshvert(& bot->pts[1]);
- OPT_OUTVERT(bot->pts[1], backend);
- for(i=topd_left; i<= top->npts-2; i++)
- {
- // backend.tmeshvert(& top->pts[i]);
- OPT_OUTVERT(top->pts[i], backend);
- }
- backend.endtfan();
- }
- if(topd_right > 1)
- {
- backend.bgntfan();
- OPT_OUTVERT(bot->pts[bot->npts-2], backend);
- for(i=1; i<= topd_right; i++)
- OPT_OUTVERT(top->pts[i], backend);
- backend.endtfan();
- }
- }
-
- if(topd_left <= topd_right)
- return;
-
- backend.bgnqstrip();
- for(j=botd_left, i=topd_left; i>=topd_right; i--,j++)
- {
- // backend.tmeshvert(& top->pts[i]);
- // backend.tmeshvert(& bot->pts[j]);
- OPT_OUTVERT(top->pts[i], backend);
- OPT_OUTVERT(bot->pts[j], backend);
- }
- backend.endqstrip();
-
- }
- }
-}
-
-
-static void triangulateRectCenter(int n_ulines, REAL* u_val,
- int n_vlines, REAL* v_val,
- Backend& backend)
-{
-
- // XXX this code was patched by Diego Santa Cruz <Diego.SantaCruz@epfl.ch>
- // to fix a problem in which glMapGrid2f() was called with bad parameters.
- // This has beens submitted to SGI but not integrated as of May 1, 2001.
- if(n_ulines>1 && n_vlines>1) {
- backend.surfgrid(u_val[0], u_val[n_ulines-1], n_ulines-1,
- v_val[n_vlines-1], v_val[0], n_vlines-1);
- backend.surfmesh(0,0,n_ulines-1,n_vlines-1);
- }
-
- return;
-
- /*
- for(i=0; i<n_vlines-1; i++)
- {
-
- backend.bgnqstrip();
- for(j=0; j<n_ulines; j++)
- {
- trimVert.param[0] = u_val[j];
- trimVert.param[1] = v_val[i+1];
- backend.tmeshvert(& trimVert);
-
- trimVert.param[1] = v_val[i];
- backend.tmeshvert(& trimVert);
- }
- backend.endqstrip();
-
- }
- */
-}
-
-//it works for top, bot, left ad right, you need ot select correct arguments
-static void triangulateRectTopGen(Arc_ptr arc, int n_ulines, REAL* u_val, Real v, int dir, int is_u, Backend& backend)
-{
-
- if(is_u)
- {
- int i,k;
- REAL* upper_val = (REAL*) malloc(sizeof(REAL) * arc->pwlArc->npts);
- assert(upper_val);
- if(dir)
- {
- for(k=0,i=arc->pwlArc->npts-1; i>=0; i--,k++)
- {
- upper_val[k] = arc->pwlArc->pts[i].param[0];
- }
- backend.evalUStrip(arc->pwlArc->npts, arc->pwlArc->pts[0].param[1],
- upper_val,
- n_ulines, v, u_val);
- }
- else
- {
- for(k=0,i=0; i<arc->pwlArc->npts; i++,k++)
- {
- upper_val[k] = arc->pwlArc->pts[i].param[0];
-
- }
-
- backend.evalUStrip(
- n_ulines, v, u_val,
- arc->pwlArc->npts, arc->pwlArc->pts[0].param[1], upper_val
- );
- }
-
- free(upper_val);
- return;
- }
- else //is_v
- {
- int i,k;
- REAL* left_val = (REAL*) malloc(sizeof(REAL) * arc->pwlArc->npts);
- assert(left_val);
- if(dir)
- {
- for(k=0,i=arc->pwlArc->npts-1; i>=0; i--,k++)
- {
- left_val[k] = arc->pwlArc->pts[i].param[1];
- }
- backend.evalVStrip(arc->pwlArc->npts, arc->pwlArc->pts[0].param[0],
- left_val,
- n_ulines, v, u_val);
- }
- else
- {
- for(k=0,i=0; i<arc->pwlArc->npts; i++,k++)
- {
- left_val[k] = arc->pwlArc->pts[i].param[1];
- }
- backend.evalVStrip(
- n_ulines, v, u_val,
- arc->pwlArc->npts, arc->pwlArc->pts[0].param[0], left_val
- );
- }
- free(left_val);
- return;
- }
-
- //the following is a different version of the above code. If you comment
- //the above code, the following code will still work. The reason to leave
- //the folliwng code here is purely for testing purpose.
- /*
- int i,j;
- PwlArc* parc = arc->pwlArc;
- int d1 = parc->npts-1;
- int d2 = 0;
- TrimVertex trimVert;
- trimVert.nuid = 0;//????
- REAL* temp_u_val = u_val;
- if(dir ==0) //have to reverse u_val
- {
- temp_u_val = (REAL*) malloc(sizeof(REAL) * n_ulines);
- assert(temp_u_val);
- for(i=0; i<n_ulines; i++)
- temp_u_val[i] = u_val[n_ulines-1-i];
- }
- u_val = temp_u_val;
-
- if(parc->npts > n_ulines)
- {
- d1 = n_ulines-1;
-
- backend.bgntfan();
- if(is_u){
- trimVert.param[0] = u_val[0];
- trimVert.param[1] = v;
- }
- else
- {
- trimVert.param[1] = u_val[0];
- trimVert.param[0] = v;
- }
-
- backend.tmeshvert(& trimVert);
- for(i=d1; i< parc->npts; i++)
- backend.tmeshvert(& parc->pts[i]);
- backend.endtfan();
-
-
- }
- else if(parc->npts < n_ulines)
- {
- d2 = n_ulines-parc->npts;
-
-
- backend.bgntfan();
- backend.tmeshvert(& parc->pts[parc->npts-1]);
- for(i=0; i<= d2; i++)
- {
- if(is_u){
- trimVert.param[0] = u_val[i];
- trimVert.param[1] = v;
- }
- else
- {
- trimVert.param[1] = u_val[i];
- trimVert.param[0] = v;
- }
- backend.tmeshvert(&trimVert);
- }
- backend.endtfan();
-
- }
- if(d1>0){
-
-
- backend.bgnqstrip();
- for(i=d1, j=d2; i>=0; i--, j++)
- {
- backend.tmeshvert(& parc->pts[i]);
-
- if(is_u){
- trimVert.param[0] = u_val[j];
- trimVert.param[1] = v;
- }
- else{
- trimVert.param[1] = u_val[j];
- trimVert.param[0] = v;
- }
- backend.tmeshvert(&trimVert);
-
-
-
- }
- backend.endqstrip();
-
-
- }
- if(dir == 0) //temp_u_val was mallocated
- free(temp_u_val);
- */
-}
-
-//n_ulines is the number of ulines inside, and n_vlines is the number of vlines
-//inside, different from meanings elsewhere!!!
-static void triangulateRectGen(Arc_ptr loop, int n_ulines, int n_vlines, Backend& backend)
-{
-
- int i;
- //we know the loop is a rectangle, but not sure which is top
- Arc_ptr top, bot, left, right;
-
- if(equalRect(loop->tail()[1] , loop->head()[1]))
- {
-
- if(loop->tail()[1] > loop->prev->prev->tail()[1])
- {
-
- top = loop;
- }
- else{
-
- top = loop->prev->prev;
- }
- }
- else
- {
- if(loop->tail()[0] > loop->prev->prev->tail()[0])
- {
- //loop is the right arc
-
- top = loop->next;
- }
- else
- {
-
- top = loop->prev;
- }
- }
-
- left = top->next;
- bot = left->next;
- right= bot->next;
-
-#ifdef COUNT_TRIANGLES
- num_triangles += loop->pwlArc->npts +
- left->pwlArc->npts +
- bot->pwlArc->npts +
- right->pwlArc->npts
- + 2*n_ulines + 2*n_vlines
- -8;
- num_quads += (n_ulines-1)*(n_vlines-1);
-#endif
-/*
- backend.surfgrid(left->tail()[0], right->tail()[0], n_ulines+1,
- top->tail()[1], bot->tail()[1], n_vlines+1);
-// if(n_ulines>1 && n_vlines>1)
- backend.surfmesh(0,0,n_ulines+1,n_vlines+1);
-return;
-*/
- REAL* u_val=(REAL*) malloc(sizeof(REAL)*n_ulines);
- assert(u_val);
- REAL* v_val=(REAL*)malloc(sizeof(REAL) * n_vlines);
- assert(v_val);
- REAL u_stepsize = (right->tail()[0] - left->tail()[0])/( (REAL) n_ulines+1);
- REAL v_stepsize = (top->tail()[1] - bot->tail()[1])/( (REAL) n_vlines+1);
- Real temp=left->tail()[0]+u_stepsize;
- for(i=0; i<n_ulines; i++)
- {
- u_val[i] = temp;
- temp += u_stepsize;
- }
- temp = bot->tail()[1] + v_stepsize;
- for(i=0; i<n_vlines; i++)
- {
- v_val[i] = temp;
- temp += v_stepsize;
- }
-
- triangulateRectTopGen(top, n_ulines, u_val, v_val[n_vlines-1], 1,1, backend);
- triangulateRectTopGen(bot, n_ulines, u_val, v_val[0], 0, 1, backend);
- triangulateRectTopGen(left, n_vlines, v_val, u_val[0], 1, 0, backend);
- triangulateRectTopGen(right, n_vlines, v_val, u_val[n_ulines-1], 0,0, backend);
-
-
-
-
- //triangulate the center
- triangulateRectCenter(n_ulines, u_val, n_vlines, v_val, backend);
-
- free(u_val);
- free(v_val);
-
-}
-
-
-
-
-/**********for reading newtess_flag from a file**********/
-#ifdef USE_READ_FLAG
-static Int read_flag(char* name)
-{
- Int ret;
- FILE* fp = fopen(name, "r");
- if(fp == NULL)
- {
- fprintf(stderr, "can't open file %s\n", name);
- exit(1);
- }
- fscanf(fp, "%i", &ret);
- fclose(fp);
- return ret;
-}
-#endif
-
-/***********nextgen tess****************/
-#include "sampleMonoPoly.h"
-directedLine* arcToDLine(Arc_ptr arc)
-{
- int i;
- Real vert[2];
- directedLine* ret;
- sampledLine* sline = new sampledLine(arc->pwlArc->npts);
- for(i=0; i<arc->pwlArc->npts; i++)
- {
- vert[0] = arc->pwlArc->pts[i].param[0];
- vert[1] = arc->pwlArc->pts[i].param[1];
- sline->setPoint(i, vert);
- }
- ret = new directedLine(INCREASING, sline);
- return ret;
-}
-
-/*an pwlArc may not be a straight line*/
-directedLine* arcToMultDLines(directedLine* original, Arc_ptr arc)
-{
- directedLine* ret = original;
- int is_linear = 0;
- if(arc->pwlArc->npts == 2 )
- is_linear = 1;
- else if(area(arc->pwlArc->pts[0].param, arc->pwlArc->pts[1].param, arc->pwlArc->pts[arc->pwlArc->npts-1].param) == 0.0)
- is_linear = 1;
-
- if(is_linear)
- {
- directedLine *dline = arcToDLine(arc);
- if(ret == NULL)
- ret = dline;
- else
- ret->insert(dline);
- return ret;
- }
- else /*not linear*/
- {
- for(Int i=0; i<arc->pwlArc->npts-1; i++)
- {
- Real vert[2][2];
- vert[0][0] = arc->pwlArc->pts[i].param[0];
- vert[0][1] = arc->pwlArc->pts[i].param[1];
- vert[1][0] = arc->pwlArc->pts[i+1].param[0];
- vert[1][1] = arc->pwlArc->pts[i+1].param[1];
-
- sampledLine *sline = new sampledLine(2, vert);
- directedLine *dline = new directedLine(INCREASING, sline);
- if(ret == NULL)
- ret = dline;
- else
- ret->insert(dline);
- }
- return ret;
- }
-}
-
-
-
-directedLine* arcLoopToDLineLoop(Arc_ptr loop)
-{
- directedLine* ret;
-
- if(loop == NULL)
- return NULL;
- ret = arcToMultDLines(NULL, loop);
-//ret->printSingle();
- for(Arc_ptr temp = loop->next; temp != loop; temp = temp->next){
- ret = arcToMultDLines(ret, temp);
-//ret->printSingle();
- }
-
- return ret;
-}
-
-/*
-void Slicer::evalRBArray(rectBlockArray* rbArray, gridWrap* grid)
-{
- TrimVertex *trimVert = (TrimVertex*)malloc(sizeof(TrimVertex));
- trimVert -> nuid = 0;//????
-
- Real* u_values = grid->get_u_values();
- Real* v_values = grid->get_v_values();
-
- Int i,j,k,l;
-
- for(l=0; l<rbArray->get_n_elements(); l++)
- {
- rectBlock* block = rbArray->get_element(l);
- for(k=0, i=block->get_upGridLineIndex(); i>block->get_lowGridLineIndex(); i--, k++)
- {
-
- backend.bgnqstrip();
- for(j=block->get_leftIndices()[k+1]; j<= block->get_rightIndices()[k+1]; j++)
- {
- trimVert->param[0] = u_values[j];
- trimVert->param[1] = v_values[i];
- backend.tmeshvert(trimVert);
-
- trimVert->param[1] = v_values[i-1];
- backend.tmeshvert(trimVert);
-
- }
- backend.endqstrip();
-
- }
- }
-
- free(trimVert);
-}
-*/
-
-void Slicer::evalRBArray(rectBlockArray* rbArray, gridWrap* grid)
-{
- Int i,j,k;
-
- Int n_vlines=grid->get_n_vlines();
- //the reason to switch the position of v_max and v_min is because of the
- //the orientation problem. glEvalMesh generates quad_strip clockwise, but
- //we need counter-clockwise.
- backend.surfgrid(grid->get_u_min(), grid->get_u_max(), grid->get_n_ulines()-1,
- grid->get_v_max(), grid->get_v_min(), n_vlines-1);
-
-
- for(j=0; j<rbArray->get_n_elements(); j++)
- {
- rectBlock* block = rbArray->get_element(j);
- Int low = block->get_lowGridLineIndex();
- Int high = block->get_upGridLineIndex();
-
- for(k=0, i=high; i>low; i--, k++)
- {
- backend.surfmesh(block->get_leftIndices()[k+1], n_vlines-1-i, block->get_rightIndices()[k+1]-block->get_leftIndices()[k+1], 1);
- }
- }
-}
-
-
-void Slicer::evalStream(primStream* pStream)
-{
- Int i,j,k;
- k=0;
-/* TrimVertex X;*/
- TrimVertex *trimVert =/*&X*/ (TrimVertex*)malloc(sizeof(TrimVertex));
- trimVert -> nuid = 0;//???
- Real* vertices = pStream->get_vertices(); //for efficiency
- for(i=0; i<pStream->get_n_prims(); i++)
- {
-
- //ith primitive has #vertices = lengths[i], type=types[i]
- switch(pStream->get_type(i)){
- case PRIMITIVE_STREAM_FAN:
-
- backend.bgntfan();
-
- for(j=0; j<pStream->get_length(i); j++)
- {
- trimVert->param[0] = vertices[k];
- trimVert->param[1] = vertices[k+1];
- backend.tmeshvert(trimVert);
-
-// backend.tmeshvert(vertices[k], vertices[k+1]);
- k += 2;
- }
- backend.endtfan();
- break;
-
- default:
- fprintf(stderr, "evalStream: not implemented yet\n");
- exit(1);
-
- }
- }
- free(trimVert);
-}
-
-
-
-
-void Slicer::slice_new(Arc_ptr loop)
-{
-//count++;
-//if(count == 78) count=1;
-//printf("count=%i\n", count);
-//if( ! (4<= count && count <=4)) return;
-
-
- Int num_ulines;
- Int num_vlines;
- Real uMin, uMax, vMin, vMax;
- Real mydu, mydv;
- uMin = uMax = loop->tail()[0];
- vMin = vMax = loop->tail()[1];
- mydu = (du>0)? du: -du;
- mydv = (dv>0)? dv: -dv;
-
- for(Arc_ptr jarc=loop->next; jarc != loop; jarc = jarc->next)
- {
-
- if(jarc->tail()[0] < uMin)
- uMin = jarc->tail()[0];
- if(jarc->tail()[0] > uMax)
- uMax = jarc->tail()[0];
- if(jarc->tail()[1] < vMin)
- vMin = jarc->tail()[1];
- if(jarc->tail()[1] > vMax)
- vMax = jarc->tail()[1];
- }
-
- if (uMax == uMin)
- return; // prevent divide-by-zero. Jon Perry. 17 June 2002
-
- if(mydu > uMax - uMin)
- num_ulines = 2;
- else
- {
- num_ulines = 3 + (Int) ((uMax-uMin)/mydu);
- }
- if(mydv>=vMax-vMin)
- num_vlines = 2;
- else
- {
- num_vlines = 2+(Int)((vMax-vMin)/mydv);
- }
-
- Int isRect = is_rect(loop);
-
- if(isRect && (num_ulines<=2 || num_vlines<=2))
- {
- if(vlinear)
- triangulateRect(loop, backend, 1, ulinear, vlinear);
- else if(ulinear)
- triangulateRect(loop, backend, -1, ulinear, vlinear);
- else
- triangulateRect(loop, backend, 0, ulinear, vlinear);
- }
-
- else if(isRect)
- {
- triangulateRectGen(loop, num_ulines-2, num_vlines-2, backend);
- }
- else if( (num_ulines<=2 || num_vlines <=2) && ulinear)
- {
- monoTriangulationFunBackend(loop, compV2InY, &backend);
- }
- else if( (!ulinear) && (!vlinear) && (num_ulines == 2) && (num_vlines > 2))
- {
- monoTriangulationFunBackend(loop, compV2InY, &backend);
- }
- else
- {
- directedLine* poly = arcLoopToDLineLoop(loop);
-
- gridWrap grid(num_ulines, num_vlines, uMin, uMax, vMin, vMax);
- primStream pStream(20, 20);
- rectBlockArray rbArray(20);
-
- sampleMonoPoly(poly, &grid, ulinear, vlinear, &pStream, &rbArray);
-
- evalStream(&pStream);
-
- evalRBArray(&rbArray, &grid);
-
-#ifdef COUNT_TRIANGLES
- num_triangles += pStream.num_triangles();
- num_quads += rbArray.num_quads();
-#endif
- poly->deleteSinglePolygonWithSline();
- }
-
-#ifdef COUNT_TRIANGLES
- printf("num_triangles=%i\n", num_triangles);
- printf("num_quads = %i\n", num_quads);
-#endif
-}
-
-void Slicer::slice(Arc_ptr loop)
-{
-#ifdef USE_READ_FLAG
- if(read_flag("flagFile"))
- slice_new(loop);
- else
- slice_old(loop);
-
-#else
- slice_new(loop);
-#endif
-
-}
-
-
-
-Slicer::Slicer( Backend &b )
- : CoveAndTiler( b ), Mesher( b ), backend( b )
-{
- oneOverDu = 0;
- du = 0;
- dv = 0;
- isolines = 0;
- ulinear = 0;
- vlinear = 0;
-}
-
-Slicer::~Slicer()
-{
-}
-
-void
-Slicer::setisolines( int x )
-{
- isolines = x;
-}
-
-void
-Slicer::setstriptessellation( REAL x, REAL y )
-{
- assert(x > 0 && y > 0);
- du = x;
- dv = y;
- setDu( du );
-}
-
-void
-Slicer::slice_old( Arc_ptr loop )
-{
- loop->markverts();
-
- Arc_ptr extrema[4];
- loop->getextrema( extrema );
-
- unsigned int npts = loop->numpts();
- TrimRegion::init( npts, extrema[0] );
-
- Mesher::init( npts );
-
- long ulines = uarray.init( du, extrema[1], extrema[3] );
-//printf("ulines = %i\n", ulines);
- Varray varray;
- long vlines = varray.init( dv, extrema[0], extrema[2] );
-//printf("vlines = %i\n", vlines);
- long botv = 0;
- long topv;
- TrimRegion::init( varray.varray[botv] );
- getGridExtent( &extrema[0]->pwlArc->pts[0], &extrema[0]->pwlArc->pts[0] );
-
- for( long quad=0; quad<varray.numquads; quad++ ) {
- backend.surfgrid( uarray.uarray[0],
- uarray.uarray[ulines-1],
- ulines-1,
- varray.vval[quad],
- varray.vval[quad+1],
- varray.voffset[quad+1] - varray.voffset[quad] );
-
- for( long i=varray.voffset[quad]+1; i <= varray.voffset[quad+1]; i++ ) {
- topv = botv++;
- advance( topv - varray.voffset[quad],
- botv - varray.voffset[quad],
- varray.varray[botv] );
- if( i == vlines )
- getPts( extrema[2] );
- else
- getPts( backend );
- getGridExtent();
- if( isolines ) {
- outline();
- } else {
- if( canTile() )
- coveAndTile();
- else
- mesh();
- }
- }
- }
-}
-
-
-void
-Slicer::outline( void )
-{
- GridTrimVertex upper, lower;
- Hull::init( );
-
- backend.bgnoutline();
- while( (nextupper( &upper )) ) {
- if( upper.isGridVert() )
- backend.linevert( upper.g );
- else
- backend.linevert( upper.t );
- }
- backend.endoutline();
-
- backend.bgnoutline();
- while( (nextlower( &lower )) ) {
- if( lower.isGridVert() )
- backend.linevert( lower.g );
- else
- backend.linevert( lower.t );
- }
- backend.endoutline();
-}
-
-
-void
-Slicer::outline( Arc_ptr jarc )
-{
- jarc->markverts();
-
- if( jarc->pwlArc->npts >= 2 ) {
- backend.bgnoutline();
- for( int j = jarc->pwlArc->npts-1; j >= 0; j-- )
- backend.linevert( &(jarc->pwlArc->pts[j]) );
- backend.endoutline();
- }
-}
-
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * slicer.h
- *
- */
-
-#ifndef __gluslicer_h_
-#define __gluslicer_h_
-
-#include "trimregion.h"
-#include "mesher.h"
-#include "coveandtiler.h"
-#include "primitiveStream.h"
-#include "rectBlock.h"
-
-class Backend;
-class Arc;
-class TrimVertex;
-
-class Slicer : public CoveAndTiler, public Mesher {
-public:
- Slicer( Backend & );
- ~Slicer( void );
- void slice( Arc_ptr );
- void slice_old( Arc_ptr);
- void slice_new( Arc_ptr );
- void evalStream(primStream* );
- void evalRBArray(rectBlockArray* rbArray, gridWrap* grid);
-
- void outline( Arc_ptr );
- void setstriptessellation( REAL, REAL );
- void setisolines( int );
-
- void set_ulinear(int ulinear_flag)
- {
- ulinear = ulinear_flag;
- }
- void set_vlinear(int vlinear_flag)
- {
- vlinear = vlinear_flag;
- }
-private:
- Backend& backend;
- REAL oneOverDu;
- REAL du, dv;
- int isolines;
-
- void outline( void );
- void initGridlines( void );
- void advanceGridlines( long );
-
- int ulinear; //indicate whether uorder is 2 or not
- int vlinear; //indicate whether vorder is 2 or not
-};
-#endif /* __gluslicer_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * sorter.c++
- *
- */
-
-#include "glimports.h"
-#include "sorter.h"
-#include "mystdio.h"
-
-Sorter::Sorter( int _es )
-{
- es = _es;
-}
-
-void
-Sorter::qsort( void *a, int n )
-{
- qs1( (char *)a, ((char *)a)+n*es);
-}
-
-int
-Sorter::qscmp( char *, char * )
-{
- _glu_dprintf( "Sorter::qscmp: pure virtual called\n" );
- return 0;
-}
-
-
-void
-Sorter::qsexc( char *, char * )
-{
- _glu_dprintf( "Sorter::qsexc: pure virtual called\n" );
-}
-
-
-void
-Sorter::qstexc( char *, char *, char * )
-{
- _glu_dprintf( "Sorter::qstexc: pure virtual called\n" );
-}
-
-void
-Sorter::qs1( char *a, char *l )
-{
- char *i, *j;
- char *lp, *hp;
- int c;
- unsigned int n;
-
-start:
- if((n=l-a) <= (unsigned int)es)
- return;
- n = es * (n / (2*es));
- hp = lp = a+n;
- i = a;
- j = l-es;
- while(1) {
- if(i < lp) {
- if((c = qscmp(i, lp)) == 0) {
- qsexc(i, lp -= es);
- continue;
- }
- if(c < 0) {
- i += es;
- continue;
- }
- }
-
-loop:
- if(j > hp) {
- if((c = qscmp(hp, j)) == 0) {
- qsexc(hp += es, j);
- goto loop;
- }
- if(c > 0) {
- if(i == lp) {
- qstexc(i, hp += es, j);
- i = lp += es;
- goto loop;
- }
- qsexc(i, j);
- j -= es;
- i += es;
- continue;
- }
- j -= es;
- goto loop;
- }
-
- if(i == lp) {
- if(lp-a >= l-hp) {
- qs1(hp+es, l);
- l = lp;
- } else {
- qs1(a, lp);
- a = hp+es;
- }
- goto start;
- }
-
- qstexc(j, lp -= es, i);
- j = hp -= es;
- }
-}
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-#ifndef __glusorter_h_
-#define __glusorter_h_
-
-class Sorter {
-public:
- Sorter( int es );
- virtual ~Sorter() { /* silence warning*/ }
- void qsort( void *a, int n );
-
-protected:
- virtual int qscmp( char *, char * );
- virtual void qsexc( char *i, char *j ); // i<-j, j<-i
- virtual void qstexc( char *i, char *j, char *k ); // i<-k, k<-j, j<-i
-
-private:
- void qs1( char *, char * );
- int es;
-};
-#endif /* __glusorter_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * splitarcs.c++
- *
- */
-
-#include "glimports.h"
-#include "myassert.h"
-#include "mysetjmp.h"
-#include "mystdio.h"
-#include "subdivider.h"
-#include "arcsorter.h"
-#include "arc.h"
-#include "bin.h"
-
-/* local preprocessor definitions */
-#define MAXARCS 10
-
-/*----------------------------------------------------------------------------
- * Subdivider::split - split trim regions in source bin by line (param == value).
- *----------------------------------------------------------------------------
- */
-
-void
-Subdivider::split( Bin& bin, Bin& left, Bin& right, int param, REAL value )
-{
- Bin intersections, unknown;
-
- partition( bin, left, intersections, right, unknown, param, value );
-
- int count = intersections.numarcs();
- if( count % 2 ) {
-#ifndef NDEBUG
- left.show( "left" );
- intersections.show( "intersections" );
- right.show( "right" );
-#endif
- ::mylongjmp( jumpbuffer, 29 );
- }
-
- Arc_ptr arclist[MAXARCS], *list;
- if( count >= MAXARCS ) {
- list = new Arc_ptr[count];
- } else {
- list = arclist;
- }
-
- Arc_ptr jarc, *last, *lptr;
- for( last = list; (jarc=intersections.removearc()) != NULL; last++ )
- *last = jarc;
-
- if( param == 0 ) { /* sort into increasing t order */
- ArcSdirSorter sorter(*this);
- sorter.qsort( list, count );
-
- //::qsort ((void *)list, count, sizeof(Arc_ptr), (cmpfunc)compare_s);
- for( lptr=list; lptr<last; lptr+=2 )
- check_s ( lptr[0], lptr[1] );
- for( lptr=list; lptr<last; lptr+=2 )
- join_s ( left, right, lptr[0], lptr[1] );
- for( lptr=list; lptr != last; lptr++ ) {
- if( ((*lptr)->head()[0] <= value) && ((*lptr)->tail()[0] <= value) )
- left.addarc( *lptr );
- else
- right.addarc( *lptr );
- }
- } else { /* sort into decreasing s order */
- ArcTdirSorter sorter(*this);
- sorter.qsort( list, count );
- //::qsort ((void *)list, count, sizeof(Arc_ptr), (cmpfunc)compare_t);
- for( lptr=list; lptr<last; lptr+=2 )
- check_t ( lptr[0], lptr[1] );
- for( lptr=list; lptr<last; lptr+=2 )
- join_t ( left, right, lptr[0], lptr[1] );
- for( lptr=list; lptr != last; lptr++ ) {
- if( ((*lptr)->head()[1] <= value) && ((*lptr)->tail()[1] <= value) )
- left.addarc( *lptr );
- else
- right.addarc( *lptr );
- }
- }
-
- if( list != arclist ) delete[] list;
- unknown.adopt();
-}
-
-
-void
-Subdivider::check_s( Arc_ptr jarc1, Arc_ptr jarc2 )
-{
- assert( jarc1->check( ) != 0 );
- assert( jarc2->check( ) != 0 );
- assert( jarc1->next->check( ) != 0 );
- assert( jarc2->next->check( ) != 0 );
- assert( jarc1 != jarc2 );
-
- /* XXX - if these assertions fail, it is due to user error or
- undersampling */
- if( ! ( jarc1->tail()[0] < (jarc1)->head()[0] ) ) {
-#ifndef NDEBUG
- _glu_dprintf( "s difference %f\n", (jarc1)->tail()[0] - (jarc1)->head()[0] );
-#endif
- ::mylongjmp( jumpbuffer, 28 );
- }
-
- if( ! ( jarc2->tail()[0] > (jarc2)->head()[0] ) ) {
-#ifndef NDEBUG
- _glu_dprintf( "s difference %f\n", (jarc2)->tail()[0] - (jarc2)->head()[0] );
-#endif
- ::mylongjmp( jumpbuffer, 28 );
- }
-}
-
-inline void
-Subdivider::link( Arc_ptr jarc1, Arc_ptr jarc2, Arc_ptr up, Arc_ptr down )
-{
- up->nuid = down->nuid = 0; // XXX
-
- up->next = jarc2;
- down->next = jarc1;
- up->prev = jarc1->prev;
- down->prev = jarc2->prev;
-
- down->next->prev = down;
- up->next->prev = up;
- down->prev->next = down;
- up->prev->next = up;
-}
-
-inline void
-Subdivider::simple_link( Arc_ptr jarc1, Arc_ptr jarc2 )
-{
- Arc_ptr tmp = jarc2->prev;
- jarc2->prev = jarc1->prev;
- jarc1->prev = tmp;
- jarc2->prev->next = jarc2;
- jarc1->prev->next = jarc1;
-}
-
-
-/*----------------------------------------------------------------------------
- * join - add a pair of oppositely directed jordan arcs between two arcs
- *----------------------------------------------------------------------------
- */
-
-void
-Subdivider::join_s( Bin& left, Bin& right, Arc_ptr jarc1, Arc_ptr jarc2 )
-{
- assert( jarc1->check( ) != 0);
- assert( jarc2->check( ) != 0);
- assert( jarc1 != jarc2 );
-
- if( ! jarc1->getitail() )
- jarc1 = jarc1->next;
-
- if( ! jarc2->getitail() )
- jarc2 = jarc2->next;
-
- REAL s = jarc1->tail()[0];
- REAL t1 = jarc1->tail()[1];
- REAL t2 = jarc2->tail()[1];
-
- if( t1 == t2 ) {
- simple_link( jarc1, jarc2 );
- } else {
- Arc_ptr newright = new(arcpool) Arc( arc_right, 0 );
- Arc_ptr newleft = new(arcpool) Arc( arc_left, 0 );
- assert( t1 < t2 );
- if( isBezierArcType() ) {
- arctessellator.bezier( newright, s, s, t1, t2 );
- arctessellator.bezier( newleft, s, s, t2, t1 );
- } else {
- arctessellator.pwl_right( newright, s, t1, t2, stepsizes[0] );
- arctessellator.pwl_left( newleft, s, t2, t1, stepsizes[2] );
- }
- link( jarc1, jarc2, newright, newleft );
- left.addarc( newright );
- right.addarc( newleft );
- }
-
- assert( jarc1->check( ) != 0 );
- assert( jarc2->check( ) != 0 );
- assert( jarc1->next->check( ) != 0);
- assert( jarc2->next->check( ) != 0);
-}
-
-void
-Subdivider::check_t( Arc_ptr jarc1, Arc_ptr jarc2 )
-{
- assert( jarc1->check( ) != 0 );
- assert( jarc2->check( ) != 0 );
- assert( jarc1->next->check( ) != 0 );
- assert( jarc2->next->check( ) != 0 );
- assert( jarc1 != jarc2 );
-
- /* XXX - if these assertions fail, it is due to user error or
- undersampling */
- if( ! ( jarc1->tail()[1] < (jarc1)->head()[1] ) ) {
-#ifndef NDEBUG
- _glu_dprintf( "t difference %f\n", jarc1->tail()[1] - (jarc1)->head()[1] );
-#endif
- ::mylongjmp( jumpbuffer, 28 );
- }
-
- if( ! ( jarc2->tail()[1] > (jarc2)->head()[1] ) ) {
-#ifndef NDEBUG
- _glu_dprintf( "t difference %f\n", jarc2->tail()[1] - (jarc2)->head()[1] );
-#endif
- ::mylongjmp( jumpbuffer, 28 );
- }
-}
-
-/*----------------------------------------------------------------------------
- * join_t - add a pair of oppositely directed jordan arcs between two arcs
- *----------------------------------------------------------------------------
- */
-
-void
-Subdivider::join_t( Bin& bottom, Bin& top, Arc_ptr jarc1, Arc_ptr jarc2 )
-{
- assert( jarc1->check( ) != 0 );
- assert( jarc2->check( ) != 0 );
- assert( jarc1->next->check( ) != 0 );
- assert( jarc2->next->check( ) != 0 );
- assert( jarc1 != jarc2 );
-
- if( ! jarc1->getitail() )
- jarc1 = jarc1->next;
-
- if( ! jarc2->getitail() )
- jarc2 = jarc2->next;
-
- REAL s1 = jarc1->tail()[0];
- REAL s2 = jarc2->tail()[0];
- REAL t = jarc1->tail()[1];
-
- if( s1 == s2 ) {
- simple_link( jarc1, jarc2 );
- } else {
- Arc_ptr newtop = new(arcpool) Arc( arc_top, 0 );
- Arc_ptr newbot = new(arcpool) Arc( arc_bottom, 0 );
- assert( s1 > s2 );
- if( isBezierArcType() ) {
- arctessellator.bezier( newtop, s1, s2, t, t );
- arctessellator.bezier( newbot, s2, s1, t, t );
- } else {
- arctessellator.pwl_top( newtop, t, s1, s2, stepsizes[1] );
- arctessellator.pwl_bottom( newbot, t, s2, s1, stepsizes[3] );
- }
- link( jarc1, jarc2, newtop, newbot );
- bottom.addarc( newtop );
- top.addarc( newbot );
- }
-
- assert( jarc1->check( ) != 0 );
- assert( jarc2->check( ) != 0 );
- assert( jarc1->next->check( ) != 0 );
- assert( jarc2->next->check( ) != 0 );
-}
-
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * subdivider.cxx
- *
- */
-
-#include "glimports.h"
-#include "myassert.h"
-#include "mystdio.h"
-#include "subdivider.h"
-#include "arc.h"
-#include "bezierarc.h"
-#include "bin.h"
-#include "renderhints.h"
-#include "backend.h"
-#include "mapdesc.h"
-#include "quilt.h"
-#include "patchlist.h"
-#include "patch.h"
-#include "nurbsconsts.h"
-#include "trimvertpool.h"
-#include "simplemath.h"
-
-#include "polyUtil.h" //for function area()
-
-//#define PARTITION_TEST
-#ifdef PARTITION_TEST
-#include "partitionY.h"
-#include "monoTriangulation.h"
-#include "dataTransform.h"
-#include "monoChain.h"
-
-#endif
-
-
-#define OPTIMIZE_UNTRIMED_CASE
-
-
-Bin*
-Subdivider::makePatchBoundary( const REAL *from, const REAL *to )
-{
- Bin* ret = new Bin();
- REAL smin = from[0];
- REAL smax = to[0];
- REAL tmin = from[1];
- REAL tmax = to[1];
-
- pjarc = 0;
-
- Arc_ptr jarc = new(arcpool) Arc( arc_bottom, 0 );
- arctessellator.bezier( jarc, smin, smax, tmin, tmin );
- ret->addarc( jarc );
- pjarc = jarc->append( pjarc );
-
- jarc = new(arcpool) Arc( arc_right, 0 );
- arctessellator.bezier( jarc, smax, smax, tmin, tmax );
- ret->addarc( jarc );
- pjarc = jarc->append( pjarc );
-
- jarc = new(arcpool) Arc( arc_top, 0 );
- arctessellator.bezier( jarc, smax, smin, tmax, tmax );
- ret->addarc( jarc );
- pjarc = jarc->append( pjarc );
-
- jarc = new(arcpool) Arc( arc_left, 0 );
- arctessellator.bezier( jarc, smin, smin, tmax, tmin );
- ret->addarc( jarc );
- jarc->append( pjarc );
-
- assert( jarc->check() != 0 );
- return ret;
-}
-
-/*---------------------------------------------------------------------------
- * Subdivider - construct a subdivider
- *---------------------------------------------------------------------------
- */
-
-Subdivider::Subdivider( Renderhints& r, Backend& b )
- : slicer( b ),
- arctessellator( trimvertexpool, pwlarcpool ),
- arcpool( sizeof( Arc), 1, "arcpool" ),
- bezierarcpool( sizeof( BezierArc ), 1, "Bezarcpool" ),
- pwlarcpool( sizeof( PwlArc ), 1, "Pwlarcpool" ),
- renderhints( r ),
- backend( b )
-{
-}
-
-void
-Subdivider::setJumpbuffer( JumpBuffer *j )
-{
- jumpbuffer = j;
-}
-
-/*---------------------------------------------------------------------------
- * clear - reset all state after possible error condition
- *---------------------------------------------------------------------------
- */
-
-void
-Subdivider::clear( void )
-{
- trimvertexpool.clear();
- arcpool.clear();
- pwlarcpool.clear();
- bezierarcpool.clear();
-}
-
-/*---------------------------------------------------------------------------
- * ~Subdivider - destroy a subdivider
- *---------------------------------------------------------------------------
- */
-
-Subdivider::~Subdivider( void )
-{
-}
-
-/*---------------------------------------------------------------------------
- * addArc - add a bezier arc to a trim loop and to a bin
- *---------------------------------------------------------------------------
- */
-void
-Subdivider::addArc( REAL *cpts, Quilt *quilt, long _nuid )
-{
- BezierArc *bezierArc = new(bezierarcpool) BezierArc;
- Arc *jarc = new(arcpool) Arc( arc_none, _nuid );
- jarc->pwlArc = 0;
- jarc->bezierArc = bezierArc;
- bezierArc->order = quilt->qspec->order;
- bezierArc->stride = quilt->qspec->stride;
- bezierArc->mapdesc = quilt->mapdesc;
- bezierArc->cpts = cpts;
- initialbin.addarc( jarc );
- pjarc = jarc->append( pjarc );
-}
-
-/*---------------------------------------------------------------------------
- * addArc - add a pwl arc to a trim loop and to a bin
- *---------------------------------------------------------------------------
- */
-
-void
-Subdivider::addArc( int npts, TrimVertex *pts, long _nuid )
-{
- Arc *jarc = new(arcpool) Arc( arc_none, _nuid );
- jarc->pwlArc = new(pwlarcpool) PwlArc( npts, pts );
- initialbin.addarc( jarc );
- pjarc = jarc->append( pjarc );
-}
-
-void
-Subdivider::beginQuilts( void )
-{
- qlist = 0;
-}
-
-void
-Subdivider::addQuilt( Quilt *quilt )
-{
- quilt->next = qlist;
- qlist = quilt;
-}
-
-/*---------------------------------------------------------------------------
- * drawSurfaces - main entry point for surface tessellation
- *---------------------------------------------------------------------------
- */
-
-void
-Subdivider::drawSurfaces( long nuid )
-{
- renderhints.init( );
-
- if (qlist == NULL)
- {
- //initialbin could be nonempty due to some errors
- freejarcs(initialbin);
- return;
- }
-
- for( Quilt *q = qlist; q; q = q->next ) {
- if( q->isCulled( ) == CULL_TRIVIAL_REJECT ) {
- freejarcs( initialbin );
- return;
- }
- }
-
-
- REAL from[2], to[2];
- qlist->getRange( from, to, spbrkpts, tpbrkpts );
-#ifdef OPTIMIZE_UNTRIMED_CASE
- //perform optimization only when the samplng method is
- //DOMAIN_DISTANCE and the display methdo is either
- //fill or outline_polygon.
- int optimize = (is_domain_distance_sampling && (renderhints.display_method != N_OUTLINE_PATCH));
-#endif
-
- if( ! initialbin.isnonempty() ) {
-#ifdef OPTIMIZE_UNTRIMED_CASE
- if(! optimize )
- {
-
- makeBorderTrim( from, to );
- }
-#else
- makeBorderTrim( from, to );
-#endif
- } else {
- REAL rate[2];
- qlist->findRates( spbrkpts, tpbrkpts, rate );
-
- if( decompose( initialbin, min(rate[0], rate[1]) ) )
- mylongjmp( jumpbuffer, 31 );
- }
-
- backend.bgnsurf( renderhints.wiretris, renderhints.wirequads, nuid );
-
-#ifdef PARTITION_TEST
- if( initialbin.isnonempty() && spbrkpts.end-2 == spbrkpts.start &&
- tpbrkpts.end-2 == tpbrkpts.start)
-{
- for(int i=spbrkpts.start; i<spbrkpts.end-1; i++){
- for(int j=tpbrkpts.start; j<tpbrkpts.end-1; j++){
- Real pta[2], ptb[2];
- pta[0] = spbrkpts.pts[i];
- ptb[0] = spbrkpts.pts[i+1];
- pta[1] = tpbrkpts.pts[j];
- ptb[1] = tpbrkpts.pts[j+1];
- qlist->downloadAll(pta, ptb, backend);
-
- directedLine *poly;
-
- {
-
- poly = bin_to_DLineLoops(initialbin);
-
- poly=poly->deleteDegenerateLinesAllPolygons();
-
- sampledLine* retSampledLines;
-//printf("before MC_partition\n");
- poly = MC_partitionY(poly, &retSampledLines);
-//printf("after MC_partition\n");
-
- }
-
-
- {
- primStream pStream(5000,5000);
- directedLine* temp;
-
- for(temp=poly; temp != NULL; temp=temp->getNextPolygon())
-
- monoTriangulation(temp, &pStream);
-
- slicer.evalStream(&pStream);
-
- }
- //need to clean up space
- }
- }
- freejarcs( initialbin );
- backend.endsurf();
- return;
-
- /*
- printf("num_polygons=%i\n", poly->numPolygons());
- printf("num_edges=%i\n", poly->numEdgesAllPolygons());
- poly->writeAllPolygons("zloutputFile");
- return;
- {
- primStream pStream(20,20);
- for(directedLine* tempD = poly; tempD != NULL; tempD = tempD->getNextPolygon())
- monoTriangulation(tempD, &pStream);
- }
- return;
- */
-}
-#endif //PARTITION_TEST
-
-
-#ifdef OPTIMIZE_UNTRIMED_CASE
- if( (!initialbin.isnonempty()) && optimize )
- {
- int i,j;
- int num_u_steps;
- int num_v_steps;
- for(i=spbrkpts.start; i<spbrkpts.end-1; i++){
- for(j=tpbrkpts.start; j<tpbrkpts.end-1; j++){
- Real pta[2], ptb[2];
- pta[0] = spbrkpts.pts[i];
- ptb[0] = spbrkpts.pts[i+1];
- pta[1] = tpbrkpts.pts[j];
- ptb[1] = tpbrkpts.pts[j+1];
- qlist->downloadAll(pta, ptb, backend);
-
- num_u_steps = (int) (domain_distance_u_rate * (ptb[0]-pta[0]));
- num_v_steps = (int) (domain_distance_v_rate * (ptb[1]-pta[1]));
-
- if(num_u_steps <= 0) num_u_steps = 1;
- if(num_v_steps <= 0) num_v_steps = 1;
-
- backend.surfgrid(pta[0], ptb[0], num_u_steps,
- ptb[1], pta[1], num_v_steps);
- backend.surfmesh(0,0,num_u_steps,num_v_steps);
-
-
-
- continue;
- /* the following is left for reference purpose, don't delete
- {
- Bin* tempSource;
- Patchlist patchlist(qlist, pta, ptb);
- patchlist.getstepsize();
-
- tempSource=makePatchBoundary(pta, ptb);
-
- tessellation(*tempSource, patchlist);
-
- render(*tempSource);
- delete tempSource;
- }
- */
- }
- }
- }
- else
- subdivideInS( initialbin );
-#else
-
- subdivideInS( initialbin );
-#endif
-
- backend.endsurf();
-
-}
-
-void
-Subdivider::subdivideInS( Bin& source )
-{
- if( renderhints.display_method == N_OUTLINE_PARAM ) {
- outline( source );
- freejarcs( source );
- } else {
- setArcTypeBezier();
- setNonDegenerate();
- splitInS( source, spbrkpts.start, spbrkpts.end );
- }
-}
-
-
-/*---------------------------------------------------------------------------
- * splitInS - split a patch and a bin by an isoparametric line
- *---------------------------------------------------------------------------
- */
-
-void
-Subdivider::splitInS( Bin& source, int start, int end )
-{
- if( source.isnonempty() ) {
- if( start != end ) {
- int i = start + (end - start) / 2;
- Bin left, right;
- split( source, left, right, 0, spbrkpts.pts[i] );
- splitInS( left, start, i );
- splitInS( right, i+1, end );
- } else {
- if( start == spbrkpts.start || start == spbrkpts.end ) {
- freejarcs( source );
- } else if( renderhints.display_method == N_OUTLINE_PARAM_S ) {
- outline( source );
- freejarcs( source );
- } else {
- setArcTypeBezier();
- setNonDegenerate();
- s_index = start;
- splitInT( source, tpbrkpts.start, tpbrkpts.end );
- }
- }
- }
-}
-
-/*---------------------------------------------------------------------------
- * splitInT - split a patch and a bin by an isoparametric line
- *---------------------------------------------------------------------------
- */
-
-void
-Subdivider::splitInT( Bin& source, int start, int end )
-{
- if( source.isnonempty() ) {
- if( start != end ) {
- int i = start + (end - start) / 2;
- Bin left, right;
- split( source, left, right, 1, tpbrkpts.pts[i] );
- splitInT( left, start, i );
- splitInT( right, i+1, end );
- } else {
- if( start == tpbrkpts.start || start == tpbrkpts.end ) {
- freejarcs( source );
- } else if( renderhints.display_method == N_OUTLINE_PARAM_ST ) {
- outline( source );
- freejarcs( source );
- } else {
- t_index = start;
- setArcTypeBezier();
- setDegenerate();
-
- REAL pta[2], ptb[2];
- pta[0] = spbrkpts.pts[s_index-1];
- pta[1] = tpbrkpts.pts[t_index-1];
-
- ptb[0] = spbrkpts.pts[s_index];
- ptb[1] = tpbrkpts.pts[t_index];
- qlist->downloadAll( pta, ptb, backend );
-
- Patchlist patchlist( qlist, pta, ptb );
-/*
-printf("-------samplingSplit-----\n");
-source.show("samplingSplit source");
-*/
- samplingSplit( source, patchlist, renderhints.maxsubdivisions, 0 );
- setNonDegenerate();
- setArcTypeBezier();
- }
- }
- }
-}
-
-/*--------------------------------------------------------------------------
- * samplingSplit - recursively subdivide patch, cull check each subpatch
- *--------------------------------------------------------------------------
- */
-
-void
-Subdivider::samplingSplit(
- Bin& source,
- Patchlist& patchlist,
- int subdivisions,
- int param )
-{
- if( ! source.isnonempty() ) return;
-
- if( patchlist.cullCheck() == CULL_TRIVIAL_REJECT ) {
- freejarcs( source );
- return;
- }
-
- patchlist.getstepsize();
-
- if( renderhints.display_method == N_OUTLINE_PATCH ) {
- tessellation( source, patchlist );
- outline( source );
- freejarcs( source );
- return;
- }
-
- //patchlist.clamp();
-
- tessellation( source, patchlist );
-
- if( patchlist.needsSamplingSubdivision() && (subdivisions > 0) ) {
- if( ! patchlist.needsSubdivision( 0 ) )
- param = 1;
- else if( ! patchlist.needsSubdivision( 1 ) )
- param = 0;
- else
- param = 1 - param;
-
- Bin left, right;
- REAL mid = ( patchlist.pspec[param].range[0] +
- patchlist.pspec[param].range[1] ) * 0.5;
- split( source, left, right, param, mid );
- Patchlist subpatchlist( patchlist, param, mid );
- samplingSplit( left, subpatchlist, subdivisions-1, param );
- samplingSplit( right, patchlist, subdivisions-1, param );
- } else {
- setArcTypePwl();
- setDegenerate();
- nonSamplingSplit( source, patchlist, subdivisions, param );
- setDegenerate();
- setArcTypeBezier();
- }
-}
-
-void
-Subdivider::nonSamplingSplit(
- Bin& source,
- Patchlist& patchlist,
- int subdivisions,
- int param )
-{
- if( patchlist.needsNonSamplingSubdivision() && (subdivisions > 0) ) {
- param = 1 - param;
-
- Bin left, right;
- REAL mid = ( patchlist.pspec[param].range[0] +
- patchlist.pspec[param].range[1] ) * 0.5;
- split( source, left, right, param, mid );
- Patchlist subpatchlist( patchlist, param, mid );
- if( left.isnonempty() ) {
- if( subpatchlist.cullCheck() == CULL_TRIVIAL_REJECT )
- freejarcs( left );
- else
- nonSamplingSplit( left, subpatchlist, subdivisions-1, param );
- }
- if( right.isnonempty() ) {
- if( patchlist.cullCheck() == CULL_TRIVIAL_REJECT )
- freejarcs( right );
- else
- nonSamplingSplit( right, patchlist, subdivisions-1, param );
- }
-
- } else {
- // make bbox calls
- patchlist.bbox();
- backend.patch( patchlist.pspec[0].range[0], patchlist.pspec[0].range[1],
- patchlist.pspec[1].range[0], patchlist.pspec[1].range[1] );
-
- if( renderhints.display_method == N_OUTLINE_SUBDIV ) {
- outline( source );
- freejarcs( source );
- } else {
- setArcTypePwl();
- setDegenerate();
- findIrregularS( source );
- monosplitInS( source, smbrkpts.start, smbrkpts.end );
- }
- }
-}
-
-/*--------------------------------------------------------------------------
- * tessellation - set tessellation of interior and boundary of patch
- *--------------------------------------------------------------------------
- */
-
-void
-Subdivider::tessellation( Bin& bin, Patchlist &patchlist )
-{
- // tessellate unsampled trim curves
- tessellate( bin, patchlist.pspec[1].sidestep[1], patchlist.pspec[0].sidestep[1],
- patchlist.pspec[1].sidestep[0], patchlist.pspec[0].sidestep[0] );
-
- // set interior sampling rates
- slicer.setstriptessellation( patchlist.pspec[0].stepsize, patchlist.pspec[1].stepsize );
-
- //added by zl: set the order which will be used in slicer.c++
- slicer.set_ulinear( (patchlist.get_uorder() == 2));
- slicer.set_vlinear( (patchlist.get_vorder() == 2));
-
- // set boundary sampling rates
- stepsizes[0] = patchlist.pspec[1].stepsize;
- stepsizes[1] = patchlist.pspec[0].stepsize;
- stepsizes[2] = patchlist.pspec[1].stepsize;
- stepsizes[3] = patchlist.pspec[0].stepsize;
-}
-
-/*---------------------------------------------------------------------------
- * monosplitInS - split a patch and a bin by an isoparametric line
- *---------------------------------------------------------------------------
- */
-
-void
-Subdivider::monosplitInS( Bin& source, int start, int end )
-{
- if( source.isnonempty() ) {
- if( start != end ) {
- int i = start + (end - start) / 2;
- Bin left, right;
- split( source, left, right, 0, smbrkpts.pts[i] );
- monosplitInS( left, start, i );
- monosplitInS( right, i+1, end );
- } else {
- if( renderhints.display_method == N_OUTLINE_SUBDIV_S ) {
- outline( source );
- freejarcs( source );
- } else {
- setArcTypePwl();
- setDegenerate();
- findIrregularT( source );
- monosplitInT( source, tmbrkpts.start, tmbrkpts.end );
- }
- }
- }
-}
-
-/*---------------------------------------------------------------------------
- * monosplitInT - split a patch and a bin by an isoparametric line
- *---------------------------------------------------------------------------
- */
-
-void
-Subdivider::monosplitInT( Bin& source, int start, int end )
-{
- if( source.isnonempty() ) {
- if( start != end ) {
- int i = start + (end - start) / 2;
- Bin left, right;
- split( source, left, right, 1, tmbrkpts.pts[i] );
- monosplitInT( left, start, i );
- monosplitInT( right, i+1, end );
- } else {
- if( renderhints.display_method == N_OUTLINE_SUBDIV_ST ) {
- outline( source );
- freejarcs( source );
- } else {
-/*
-printf("*******render\n");
-source.show("source\n");
-*/
- render( source );
- freejarcs( source );
- }
- }
- }
-}
-
-
-/*----------------------------------------------------------------------------
- * findIrregularS - determine points of non-monotonicity is s direction
- *----------------------------------------------------------------------------
- */
-
-void
-Subdivider::findIrregularS( Bin& bin )
-{
- assert( bin.firstarc()->check() != 0 );
-
- smbrkpts.grow( bin.numarcs() );
-
- for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) {
- REAL *a = jarc->prev->tail();
- REAL *b = jarc->tail();
- REAL *c = jarc->head();
-
- if( b[1] == a[1] && b[1] == c[1] ) continue;
-
- //corrected code
- if((b[1]<=a[1] && b[1] <= c[1]) ||
- (b[1]>=a[1] && b[1] >= c[1]))
- {
- //each arc (jarc, jarc->prev, jarc->next) is a
- //monotone arc consisting of multiple line segements.
- //it may happen that jarc->prev and jarc->next are the same,
- //that is, jarc->prev and jarc form a closed loop.
- //In such case, a and c will be the same.
- if(a[0]==c[0] && a[1] == c[1])
- {
- if(jarc->pwlArc->npts >2)
- {
- c = jarc->pwlArc->pts[jarc->pwlArc->npts-2].param;
- }
- else
- {
- assert(jarc->prev->pwlArc->npts>2);
- a = jarc->prev->pwlArc->pts[jarc->prev->pwlArc->npts-2].param;
- }
-
- }
- if(area(a,b,c) < 0)
- {
- smbrkpts.add(b[0]);
- }
-
- }
-
- /* old code,
- if( b[1] <= a[1] && b[1] <= c[1] ) {
- if( ! ccwTurn_tr( jarc->prev, jarc ) )
- smbrkpts.add( b[0] );
- } else if( b[1] >= a[1] && b[1] >= c[1] ) {
- if( ! ccwTurn_tl( jarc->prev, jarc ) )
- smbrkpts.add( b[0] );
- }
- */
-
- }
-
- smbrkpts.filter();
-}
-
-/*----------------------------------------------------------------------------
- * findIrregularT - determine points of non-monotonicity in t direction
- * where one arc is parallel to the s axis.
- *----------------------------------------------------------------------------
- */
-
-void
-Subdivider::findIrregularT( Bin& bin )
-{
- assert( bin.firstarc()->check() != 0 );
-
- tmbrkpts.grow( bin.numarcs() );
-
- for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) {
- REAL *a = jarc->prev->tail();
- REAL *b = jarc->tail();
- REAL *c = jarc->head();
-
- if( b[0] == a[0] && b[0] == c[0] ) continue;
-
- if( b[0] <= a[0] && b[0] <= c[0] ) {
- if( a[1] != b[1] && b[1] != c[1] ) continue;
- if( ! ccwTurn_sr( jarc->prev, jarc ) )
- tmbrkpts.add( b[1] );
- } else if ( b[0] >= a[0] && b[0] >= c[0] ) {
- if( a[1] != b[1] && b[1] != c[1] ) continue;
- if( ! ccwTurn_sl( jarc->prev, jarc ) )
- tmbrkpts.add( b[1] );
- }
- }
- tmbrkpts.filter( );
-}
-
-/*-----------------------------------------------------------------------------
- * makeBorderTrim - if no user input trimming data then create
- * a trimming curve around the boundaries of the Quilt. The curve consists of
- * four Jordan arcs, one for each side of the Quilt, connected, of course,
- * head to tail.
- *-----------------------------------------------------------------------------
- */
-
-void
-Subdivider::makeBorderTrim( const REAL *from, const REAL *to )
-{
- REAL smin = from[0];
- REAL smax = to[0];
- REAL tmin = from[1];
- REAL tmax = to[1];
-
- pjarc = 0;
-
- Arc_ptr jarc = new(arcpool) Arc( arc_bottom, 0 );
- arctessellator.bezier( jarc, smin, smax, tmin, tmin );
- initialbin.addarc( jarc );
- pjarc = jarc->append( pjarc );
-
- jarc = new(arcpool) Arc( arc_right, 0 );
- arctessellator.bezier( jarc, smax, smax, tmin, tmax );
- initialbin.addarc( jarc );
- pjarc = jarc->append( pjarc );
-
- jarc = new(arcpool) Arc( arc_top, 0 );
- arctessellator.bezier( jarc, smax, smin, tmax, tmax );
- initialbin.addarc( jarc );
- pjarc = jarc->append( pjarc );
-
- jarc = new(arcpool) Arc( arc_left, 0 );
- arctessellator.bezier( jarc, smin, smin, tmax, tmin );
- initialbin.addarc( jarc );
- jarc->append( pjarc );
-
- assert( jarc->check() != 0 );
-}
-
-/*----------------------------------------------------------------------------
- * render - renders all monotone regions in a bin and frees the bin
- *----------------------------------------------------------------------------
- */
-
-void
-Subdivider::render( Bin& bin )
-{
- bin.markall();
-
-#ifdef N_ISOLINE_S
- slicer.setisolines( ( renderhints.display_method == N_ISOLINE_S ) ? 1 : 0 );
-#else
- slicer.setisolines( 0 );
-#endif
-
- for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) {
- if( jarc->ismarked() ) {
- assert( jarc->check( ) != 0 );
- Arc_ptr jarchead = jarc;
- do {
- jarc->clearmark();
- jarc = jarc->next;
- } while (jarc != jarchead);
- slicer.slice( jarc );
- }
- }
-}
-
-/*---------------------------------------------------------------------------
- * outline - render the trimmed patch by outlining the boundary
- *---------------------------------------------------------------------------
- */
-
-void
-Subdivider::outline( Bin& bin )
-{
- bin.markall();
- for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) {
- if( jarc->ismarked() ) {
- assert( jarc->check( ) != 0 );
- Arc_ptr jarchead = jarc;
- do {
- slicer.outline( jarc );
- jarc->clearmark();
- jarc = jarc->prev;
- } while (jarc != jarchead);
- }
- }
-}
-
-/*---------------------------------------------------------------------------
- * freejarcs - free all arcs in a bin
- *---------------------------------------------------------------------------
- */
-
-void
-Subdivider::freejarcs( Bin& bin )
-{
- bin.adopt(); /* XXX - should not be necessary */
-
- Arc_ptr jarc;
- while( (jarc = bin.removearc()) != NULL ) {
- if( jarc->pwlArc ) jarc->pwlArc->deleteMe( pwlarcpool ); jarc->pwlArc = 0;
- if( jarc->bezierArc) jarc->bezierArc->deleteMe( bezierarcpool ); jarc->bezierArc = 0;
- jarc->deleteMe( arcpool );
- }
-}
-
-/*----------------------------------------------------------------------------
- * tessellate - tessellate all Bezier arcs in a bin
- * 1) only accepts linear Bezier arcs as input
- * 2) the Bezier arcs are stored in the pwlArc structure
- * 3) only vertical or horizontal lines work
- * -- should
- * 1) represent Bezier arcs in BezierArc structure
- * (this requires a multitude of changes to the code)
- * 2) accept high degree Bezier arcs (hard)
- * 3) map the curve onto the surface to determine tessellation
- * 4) work for curves of arbitrary geometry
- *----------------------------------------------------------------------------
- */
-
-
-void
-Subdivider::tessellate( Bin& bin, REAL rrate, REAL trate, REAL lrate, REAL brate )
-{
- for( Arc_ptr jarc=bin.firstarc(); jarc; jarc=bin.nextarc() ) {
- if( jarc->isbezier( ) ) {
- assert( jarc->pwlArc->npts == 2 );
- TrimVertex *pts = jarc->pwlArc->pts;
- REAL s1 = pts[0].param[0];
- REAL t1 = pts[0].param[1];
- REAL s2 = pts[1].param[0];
- REAL t2 = pts[1].param[1];
-
- jarc->pwlArc->deleteMe( pwlarcpool ); jarc->pwlArc = 0;
-
- switch( jarc->getside() ) {
- case arc_left:
- assert( s1 == s2 );
- arctessellator.pwl_left( jarc, s1, t1, t2, lrate );
- break;
- case arc_right:
- assert( s1 == s2 );
- arctessellator.pwl_right( jarc, s1, t1, t2, rrate );
- break;
- case arc_top:
- assert( t1 == t2 );
- arctessellator.pwl_top( jarc, t1, s1, s2, trate );
- break;
- case arc_bottom:
- assert( t1 == t2 );
- arctessellator.pwl_bottom( jarc, t1, s1, s2, brate );
- break;
- case arc_none:
- (void) abort();
- break;
- }
- assert( ! jarc->isbezier() );
- assert( jarc->check() != 0 );
- }
- }
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * subdivider.h
- *
- */
-
-#ifndef __glusubdivider_h_
-#define __glusubdivider_h_
-
-#include "mysetjmp.h"
-#include "bin.h"
-#include "flist.h"
-#include "slicer.h"
-#include "arctess.h"
-#include "trimvertex.h"
-#include "trimvertpool.h"
-
-class Arc;
-class Pool;
-class Renderhints;
-class Quilt;
-class Patchlist;
-class Curvelist;
-struct JumpBuffer;
-
-class Subdivider {
-public:
- Subdivider( Renderhints&, Backend& );
- ~Subdivider( void );
- void clear( void );
-
- void beginTrims( void ) {}
- void beginLoop( void );
- void addArc( REAL *, Quilt *, long );
- void addArc( int, TrimVertex *, long );
- void endLoop( void ) {}
- void endTrims( void ) {}
-
- void beginQuilts( void );
- void addQuilt( Quilt * );
- void endQuilts( void ) {}
-
- void drawCurves( void );
- void drawSurfaces( long );
-
- int ccwTurn_sl( Arc_ptr, Arc_ptr );
- int ccwTurn_sr( Arc_ptr , Arc_ptr );
- int ccwTurn_tl( Arc_ptr , Arc_ptr );
- int ccwTurn_tr( Arc_ptr , Arc_ptr );
-
- void setJumpbuffer( JumpBuffer * );
-
- void set_domain_distance_u_rate(REAL u_rate)
- {
- domain_distance_u_rate = u_rate;
- }
- void set_domain_distance_v_rate(REAL v_rate)
- {
- domain_distance_v_rate = v_rate;
- }
- void set_is_domain_distance_sampling(int flag)
- {
- is_domain_distance_sampling = flag;
- }
-
-private:
- void classify_headonleft_s( Bin &, Bin &, Bin &, REAL );
- void classify_tailonleft_s( Bin &, Bin &, Bin &, REAL );
- void classify_headonright_s( Bin &, Bin &, Bin &, REAL );
- void classify_tailonright_s( Bin &, Bin &, Bin &, REAL );
- void classify_headonleft_t( Bin &, Bin &, Bin &, REAL );
- void classify_tailonleft_t( Bin &, Bin &, Bin &, REAL );
- void classify_headonright_t( Bin &, Bin &, Bin &, REAL );
- void classify_tailonright_t( Bin &, Bin &, Bin &, REAL );
-
- enum dir { down, same, up, none };
- void tessellate( Arc_ptr, REAL );
- void monotonize( Arc_ptr , Bin & );
- int isMonotone( Arc_ptr );
- int decompose( Bin &, REAL );
-
-
- Slicer slicer;
- ArcTessellator arctessellator;
- Pool arcpool;
- Pool bezierarcpool;
- Pool pwlarcpool;
- TrimVertexPool trimvertexpool;
-
- JumpBuffer* jumpbuffer;
- Renderhints& renderhints;
- Backend& backend;
-
- Bin initialbin;
- Arc_ptr pjarc;
- int s_index;
- int t_index;
- Quilt * qlist;
- Flist spbrkpts;
- Flist tpbrkpts;
- Flist smbrkpts;
- Flist tmbrkpts;
- REAL stepsizes[4];
- int showDegenerate;
- int isArcTypeBezier;
-
- void samplingSplit( Curvelist&, int );
-
- void subdivideInS( Bin& );
- void splitInS( Bin&, int, int );
- void splitInT( Bin&, int, int );
- void samplingSplit( Bin&, Patchlist&, int, int );
- void nonSamplingSplit( Bin&, Patchlist&, int, int );
- void tessellation( Bin&, Patchlist& );
- void monosplitInS( Bin&, int, int );
- void monosplitInT( Bin&, int, int );
-
- void outline( Bin & );
- void freejarcs( Bin & );
- void render( Bin & );
- void split( Bin &, Bin &, Bin &, int, REAL );
- void tessellate( Bin &, REAL, REAL, REAL, REAL );
-
- inline void setDegenerate( void ) { showDegenerate = 1; }
- inline void setNonDegenerate( void ) { showDegenerate = 0; }
- inline int showingDegenerate( void ) { return showDegenerate; }
- inline void setArcTypeBezier( void ) { isArcTypeBezier = 1; }
- inline void setArcTypePwl( void ) { isArcTypeBezier = 0; }
- inline int isBezierArcType( void ) { return isArcTypeBezier; }
-
- void makeBorderTrim( const REAL *, const REAL * );
- void split( Bin &, int, const REAL *, int, int );
- void partition( Bin &, Bin &, Bin &, Bin &, Bin &, int, REAL );
- void findIrregularS( Bin & );
- void findIrregularT( Bin & );
-
-
- inline int bbox( TrimVertex *, TrimVertex *, TrimVertex *, int );
- static int bbox( REAL, REAL, REAL, REAL, REAL, REAL );
- static int ccw( TrimVertex *, TrimVertex *, TrimVertex * );
- void join_s( Bin &, Bin &, Arc_ptr, Arc_ptr );
- void join_t( Bin &, Bin &, Arc_ptr , Arc_ptr );
- int arc_split( Arc_ptr , int, REAL, int );
- void check_s( Arc_ptr , Arc_ptr );
- void check_t( Arc_ptr , Arc_ptr );
- inline void link( Arc_ptr , Arc_ptr , Arc_ptr , Arc_ptr );
- inline void simple_link( Arc_ptr , Arc_ptr );
-
- Bin* makePatchBoundary( const REAL *from, const REAL *to );
-
- /*in domain distance method, the tessellation is controled by two numbers:
- *GLU_U_STEP: number of u-segments per unit u length of domain
- *GLU_V_STEP: number of v-segments per unit v length of domain
- *These two numbers are normally stored in mapdesc->maxs(t)rate.
- *I (ZL) put these two numbers here so that I can optimize the untrimmed
- *case in the case of domain distance sampling.
- *These two numbers are set by set_domain_distance_u_rate() and ..._v_..().
- */
- REAL domain_distance_u_rate;
- REAL domain_distance_v_rate;
- int is_domain_distance_sampling;
-};
-
-inline void
-Subdivider::beginLoop( void )
-{
- pjarc = 0;
-}
-
-
-#endif /* __glusubdivider_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * tobezier.c++
- *
- */
-
-#include "glimports.h"
-#include "myassert.h"
-#include "mystdio.h"
-#include "mystring.h"
-#include "quilt.h"
-#include "knotvector.h"
-
-/* local type definitions */
-struct Breakpt { /* breakpoints */
- Knot value; /* value */
- int multi; /* multiplicity */
- int def; /* deficit */
-};
-
-struct Knotspec { /* knotvector format */
- long order; /* order of spline */
- Knot_ptr inkbegin; /* input knot sequence */
- Knot_ptr inkend; /* location after last knot */
- Knot_ptr outkbegin; /* in-process knot subsequence */
- Knot_ptr outkend; /* location after last knot */
- Knot_ptr kleft; /* */
- Knot_ptr kright; /* */
- Knot_ptr kfirst; /* */
- Knot_ptr klast; /* */
- Knot_ptr sbegin; /* conversion factor values */
- Breakpt * bbegin; /* in-process breakpoints */
- Breakpt * bend; /* last breakpoint */
- int ncoords; /* coordinates per control point */
- int prestride; /* stride between input points */
- int poststride; /* stride between output points */
- int preoffset; /* scaled point offset */
- int postoffset; /* scaled point offset */
- int prewidth; /* width of dimension */
- int postwidth; /* width of dimension */
- int istransformed; /* was dimension transformed */
- Knotspec * next; /* next knotspec */
- Knotspec * kspectotrans; /* knotspec in transformation direction */
-
- Knotspec( void );
- ~Knotspec( void );
- void factors( void );
- void insert( REAL * );
- void preselect();
- void select( void );
- void copy( INREAL *, REAL * );
- void breakpoints( void );
- void knots( void );
- void transform( REAL * );
- void showpts( REAL * );
-
- void pt_io_copy( REAL *, INREAL * );
- void pt_oo_copy( REAL *, REAL * );
- void pt_oo_sum( REAL*, REAL*, REAL*, Knot, Knot );
-};
-
-struct Splinespec { /* a non-uniform tensor element */
- Splinespec( int );
- ~Splinespec(void);
- Knotspec *kspec; /* format of each param. dir. */
- int dim; /* domain dimension */
- REAL * outcpts; /* Bezier control points */
-
- void kspecinit( Knotvector & );
- void kspecinit( Knotvector &, Knotvector & );
- void select( void );
- void layout( long );
- void setupquilt( Quilt_ptr );
- void copy( INREAL * );
- void transform( void );
-};
-
-/*-----------------------------------------------------------------------------
- * Quilt::toBezier - convert from NURBS to rational Bezier
- *-----------------------------------------------------------------------------
- */
-
-void
-Quilt::toBezier(
- Knotvector& knotvector, /* a knot vector */
- INREAL *ctlpts, /* input contol points */
- long ncoords ) /* number of coordinates per control point */
-{
- Splinespec spline( 1 );
- spline.kspecinit( knotvector );
- spline.select();
- spline.layout( ncoords );
- spline.setupquilt( this );
- spline.copy( ctlpts );
- spline.transform();
-}
-
-void
-Quilt::toBezier(
- Knotvector& sknotvector, /* a knot vector */
- Knotvector& tknotvector, /* a knot vector */
- INREAL *ctlpts, /* input contol points */
- long ncoords ) /* number of coordinates per control point */
-{
- Splinespec spline( 2 );
- spline.kspecinit( sknotvector, tknotvector );
- spline.select();
- spline.layout( ncoords );
- spline.setupquilt( this );
- spline.copy( ctlpts );
- spline.transform();
-}
-Splinespec::Splinespec( int dimen )
-{
- dim = dimen;
-}
-
-Splinespec::~Splinespec( void )
-{
- /* Note: do NOT delete 'outcpts' here since its address (not contents)
- * is copied in 'cpts' in this file in function Splinespec::setupquilt().
- * This block of memory will eventually be deleted in file quilt.c++ in
- * function Quilt::deleteMe() through 'cpts' so do NOT delete it here!
- */
- Knotspec *ktrav= kspec; //start at beginning of list
- while (ktrav != 0) { //any items to delete?
- Knotspec *deleteThis= ktrav; //remember to delete this
- ktrav= ktrav->next; //go to next item if any
- delete deleteThis; //delete it
- }
-} /* ~Splinespec() */
-
-/*-----------------------------------------------------------------------------
- * Splinespec::kspecinit - initialize Splinespec structure
- *
- * Client: Quilt::toBezier
- *-----------------------------------------------------------------------------
- */
-
-void
-Splinespec::kspecinit( Knotvector& knotvector )
-{
- kspec = new Knotspec;
- kspec->inkbegin = knotvector.knotlist;
- kspec->inkend = knotvector.knotlist + knotvector.knotcount;
- kspec->prestride = (int) knotvector.stride;
- kspec->order = knotvector.order;
- kspec->next = NULL;
-}
-
-void
-Splinespec::kspecinit( Knotvector& sknotvector, Knotvector& tknotvector )
-{
- kspec = new Knotspec;
- Knotspec *tkspec = new Knotspec;
-
- kspec->inkbegin = sknotvector.knotlist;
- kspec->inkend = sknotvector.knotlist + sknotvector.knotcount;
- kspec->prestride = (int) sknotvector.stride;
- kspec->order = sknotvector.order;
- kspec->next = tkspec;
-
- tkspec->inkbegin = tknotvector.knotlist;
- tkspec->inkend = tknotvector.knotlist + tknotvector.knotcount;
- tkspec->prestride = (int) tknotvector.stride;
- tkspec->order = tknotvector.order;
- tkspec->next = NULL;
-}
-
-
-/*-----------------------------------------------------------------------------
- * Splinespec::select - select the subsegments to copy
- *
- * Client: gl_quilt_to_bezier
- *-----------------------------------------------------------------------------
- */
-
-void
-Splinespec::select( )
-{
- for( Knotspec *knotspec = kspec; knotspec; knotspec = knotspec->next ) {
- knotspec->preselect();
- knotspec->select();
- }
-}
-
-/*-----------------------------------------------------------------------------
- * Splinespec::layout -
- *
- * Client: gl_quilt_to_bezier
- *-----------------------------------------------------------------------------
- */
-
-void
-Splinespec::layout( long ncoords )
-{
-
- long stride = ncoords;
- for( Knotspec *knotspec = kspec; knotspec; knotspec=knotspec->next ) {
- knotspec->poststride = (int) stride;
- stride *= ((knotspec->bend-knotspec->bbegin)*knotspec->order + knotspec->postoffset);
- knotspec->preoffset *= knotspec->prestride;
- knotspec->prewidth *= knotspec->poststride;
- knotspec->postwidth *= knotspec->poststride;
- knotspec->postoffset *= knotspec->poststride;
- knotspec->ncoords = (int) ncoords;
- }
- outcpts = new REAL[stride];
- assert( outcpts != 0 );
-}
-
-/*-----------------------------------------------------------------------------
- * Splinespec::copy - copy the control points of current subobject
- *
- * Client: gl_quilt_to_bezier
- *-----------------------------------------------------------------------------
- */
-
-void
-Splinespec::copy( INREAL *incpts )
-{
- kspec->copy( incpts, outcpts );
-}
-
-/*-----------------------------------------------------------------------------
- * Splinespec::setupquilt - assign all quilt variables from knotspec
- *
- * Client: gl_quilt_to_bezier
- *-----------------------------------------------------------------------------
- */
-
-void
-Splinespec::setupquilt( Quilt_ptr quilt )
-{
- Quiltspec_ptr qspec = quilt->qspec;
- quilt->eqspec = qspec + dim;
- for( Knotspec *knotspec = kspec; knotspec; knotspec=knotspec->next, qspec++ ) {
- qspec->stride = knotspec->poststride;
- qspec->width = knotspec->bend - knotspec->bbegin;
- qspec->order = (int) knotspec->order;
- qspec->offset = knotspec->postoffset;
- qspec->index = 0;
- qspec->bdry[0] = (knotspec->kleft == knotspec->kfirst) ? 1 : 0;
- qspec->bdry[1] = (knotspec->kright == knotspec->klast) ? 1 : 0;
- qspec->breakpoints = new Knot[qspec->width+1];
- Knot_ptr k = qspec->breakpoints;
- for( Breakpt *bk = knotspec->bbegin; bk <= knotspec->bend; bk++ )
- *(k++) = bk->value;
- }
- quilt->cpts = outcpts;
- quilt->next = 0;
-}
-
-/*-----------------------------------------------------------------------------
- * Splinespec::transform - convert a spline to Bezier format
- *
- * Client: gl_quilt_to_bezier
- *-----------------------------------------------------------------------------
- */
-
-void
-Splinespec::transform( void )
-{
- Knotspec *knotspec;
- for( knotspec = kspec; knotspec; knotspec=knotspec->next )
- knotspec->istransformed = 0;
-
- for( knotspec = kspec; knotspec; knotspec=knotspec->next ) {
- for( Knotspec *kspec2 = kspec; kspec2; kspec2=kspec2->next )
- kspec2->kspectotrans = knotspec;
- kspec->transform( outcpts );
- knotspec->istransformed = 1;
- }
-}
-
-
-/*-----------------------------------------------------------------------------
- * Knotspec::Knotspec - constuct a knot spec
- *-----------------------------------------------------------------------------
- */
-
-Knotspec::Knotspec( void )
-{
- bbegin = 0;
- sbegin = 0;
- outkbegin = 0;
-}
-
-/*-----------------------------------------------------------------------------
- * Knotspec::copy - copy the control points along minor direction
- *
- * Client: Splinespec::copy
- *-----------------------------------------------------------------------------
- */
-
-void
-Knotspec::copy( INREAL *inpt, REAL *outpt )
-{
- inpt = (INREAL *) (((char *) inpt) + preoffset);
-
- if( next ) {
- for( REAL *lpt=outpt+prewidth; outpt != lpt; outpt += poststride ) {
- next->copy( inpt, outpt );
- inpt = (INREAL *) (((char *) inpt) + prestride);
- }
- } else {
- for( REAL *lpt=outpt+prewidth; outpt != lpt; outpt += poststride ) {
- pt_io_copy( outpt, inpt );
- inpt = (INREAL *) (((char *) inpt) + prestride);
- }
- }
-}
-
-/*-----------------------------------------------------------------------------
- * Knotspec::showpts - print out points before transformation
- *
- * Client: Knotspec::select
- *-----------------------------------------------------------------------------
- */
-void
-Knotspec::showpts( REAL *outpt )
-{
- if( next ) {
- for( REAL *lpt=outpt+prewidth; outpt != lpt; outpt += poststride )
- next->showpts( outpt );
- } else {
- for( REAL *lpt=outpt+prewidth; outpt != lpt; outpt += poststride )
- _glu_dprintf( "show %g %g %g\n", outpt[0], outpt[1], outpt[2] );
- }
-}
-
-/*-----------------------------------------------------------------------------
- * Knotspec::factors - precompute scale factors
- * - overwrites knot vector, actual new knot vector is NOT produced
- *
- * Client: Knotspec::select
- *-----------------------------------------------------------------------------
- */
-
-void
-Knotspec::factors( void )
-{
- Knot *mid = (outkend - 1) - order + bend->multi;
- Knot_ptr fptr = sbegin;
-
- for( Breakpt *bpt = bend; bpt >= bbegin; bpt-- ) {
- mid -= bpt->multi; // last knot less than knot to insert
- int def = bpt->def - 1; // number of knots to insert
- if( def <= 0 ) continue;
- Knot kv = bpt->value; // knot to insert
-
- Knot *kf = (mid-def) + (order-1);
- for( Knot *kl = kf + def; kl != kf; kl-- ) {
- Knot *kh, *kt;
- for( kt=kl, kh=mid; kt != kf; kh--, kt-- )
- *(fptr++) = (kv - *kh) / (*kt - *kh);
- *kl = kv;
- }
- }
-}
-
-/*-----------------------------------------------------------------------------
- * Knotspec::insert - convert subobject in direction of kspec into Bezier
- *
- * Client: Knotspec::transform
- *-----------------------------------------------------------------------------
- */
-
-void
-Knotspec::insert( REAL *p )
-{
- Knot_ptr fptr = sbegin;
- REAL *srcpt = p + prewidth - poststride;
- REAL *dstpt = p + postwidth + postoffset - poststride;
- Breakpt *bpt = bend;
-
- for( REAL *pend = srcpt - poststride*bpt->def; srcpt != pend; pend +=poststride ) {
- REAL *p1 = srcpt;
- for( REAL *p2 = srcpt-poststride; p2 != pend; p1 = p2, p2 -= poststride ) {
- pt_oo_sum( p1, p1, p2, *fptr, 1.0-*fptr );
- fptr++;
- }
- }
-
- for( --bpt; bpt >= bbegin; bpt-- ) {
-
- for( int multi = bpt->multi; multi > 0; multi-- ) {
- pt_oo_copy( dstpt, srcpt );
- dstpt -= poststride;
- srcpt -= poststride;
- }
-
- for( REAL *pend = srcpt - poststride*bpt->def; srcpt != pend; pend +=poststride, dstpt-=poststride ) {
- pt_oo_copy( dstpt, srcpt );
- REAL *p1 = srcpt;
-
- for( REAL *p2 = srcpt-poststride; p2 != pend; p1=p2, p2 -= poststride ) {
- pt_oo_sum( p1, p1, p2, *fptr, 1.0-*fptr );
- fptr++;
- }
- }
- }
-}
-
-/*-----------------------------------------------------------------------------
- * Knotspec::preselect - initialize kspec for processing
- *
- * Client: Splinespec::select
- *-----------------------------------------------------------------------------
- */
-
-void
-Knotspec::preselect( void )
-{
- Knot kval;
-
- /* position klast after last knot of "last" breakpoint */
- for( klast = inkend - order, kval = *klast; klast != inkend; klast++ )
- if( ! identical( *klast, kval ) ) break;
-
- /* position kfirst after last knot of "first" breakpoint */
- for( kfirst = inkbegin+order-1, kval= *kfirst; kfirst != inkend; kfirst++ )
- if( ! identical( *kfirst, kval ) ) break;
-
- /* compute multiplicity of first breakpoint */
- Knot_ptr k;
- for( k = kfirst - 1; k >= inkbegin; k-- )
- if( ! identical( kval, *k ) ) break;
- k++;
-
- /* allocate space for breakpoints -
- use worst case estimate on number of breakpoints */
-
- bbegin = new Breakpt[(klast - kfirst)+1];
- /* record multiplicity and value of first breakpoint */
- bbegin->multi = kfirst - k;
- bbegin->value = kval;
- bend = bbegin;
-
- kleft = kright = kfirst;
-}
-
-
-/*-----------------------------------------------------------------------------
- * Knotspec::select - Knotspec::select segments and precompute scale factors
- *
- * Client: Splinespec::select
- *-----------------------------------------------------------------------------
- */
-
-void
-Knotspec::select( void )
-{
- breakpoints();
- knots();
- factors();
-
- preoffset = kleft - (inkbegin + order);
- postwidth = (int)((bend - bbegin) * order);
- prewidth = (int)((outkend - outkbegin) - order);
- postoffset = (bbegin->def > 1) ? (bbegin->def-1) : 0;
-}
-
-/*-----------------------------------------------------------------------------
- * Knotspec::breakpoints - compute breakpoints for knotspec
- *
- * Client: Knotspec::select
- *-----------------------------------------------------------------------------
- */
-
-void
-Knotspec::breakpoints( void )
-{
- Breakpt *ubpt = bbegin;
- Breakpt *ubend = bend;
- long nfactors = 0;
-
- ubpt->value = ubend->value;
- ubpt->multi = ubend->multi;
-
- kleft = kright;
-
- for( ; kright != klast; kright++ ) {
- if ( identical(*kright,ubpt->value) ) {
- (ubpt->multi)++;
- } else {
- ubpt->def = (int) (order - ubpt->multi);
- nfactors += (ubpt->def * (ubpt->def - 1)) / 2;
- (++ubpt)->value = *kright;
- ubpt->multi = 1;
- }
- }
- ubpt->def = (int) (order - ubpt->multi);
- nfactors += (ubpt->def * (ubpt->def - 1)) / 2;
-
- bend = ubpt;
-
- if( nfactors ) {
- sbegin = new Knot[nfactors];
- } else {
- sbegin = NULL;
- }
-}
-
-
-/*-----------------------------------------------------------------------------
- * Knotspec::knots - copy relevant subsequence of knots into temporary area
- *
- * Client: Knotspec::select
- *-----------------------------------------------------------------------------
- */
-
-void
-Knotspec::knots( void )
-{
- Knot_ptr inkpt = kleft - order;
- Knot_ptr inkend = kright + bend->def;
-
- /* allocate space for knots and factors */
- outkbegin = new Knot[inkend-inkpt];
- Knot_ptr outkpt;
- for( outkpt = outkbegin; inkpt != inkend; inkpt++, outkpt++ )
- *outkpt = *inkpt;
-
- outkend = outkpt;
-}
-
-
-/*-----------------------------------------------------------------------------
- * Knotspec::transform - convert a spline along a given direction
- *
- * Client: Splienspec::transform
- *-----------------------------------------------------------------------------
- */
-
-void
-Knotspec::transform( REAL *p )
-{
- if( next ) {
- if( this == kspectotrans ) {
- next->transform( p );
- } else {
- if( istransformed ) {
- p += postoffset;
- for( REAL *pend = p + postwidth; p != pend; p += poststride )
- next->transform( p );
- } else {
- REAL *pend = p + prewidth;
- for( ; p != pend; p += poststride )
- next->transform( p );
- }
- }
- } else {
- if( this == kspectotrans ) {
- insert( p );
- } else {
- if( istransformed ) {
- p += postoffset;
- for( REAL *pend = p + postwidth; p != pend; p += poststride )
- kspectotrans->insert( p );
- } else {
- REAL *pend = p + prewidth;
- for( ; p != pend; p += poststride )
- kspectotrans->insert( p );
- }
- }
- }
-}
-
-/*-----------------------------------------------------------------------------
- * Knotspec::~Knotspec - free space alocated for knotspec
- *-----------------------------------------------------------------------------
- */
-
-Knotspec::~Knotspec( void )
-{
- if( bbegin ) delete[] bbegin;
- if( sbegin ) delete[] sbegin;
- if( outkbegin ) delete[] outkbegin;
-}
-
-
-/*-----------------------------------------------------------------------------
- * pt_io_copy - make internal copy of input cntrl pt. of x coords
- *-----------------------------------------------------------------------------
- */
-
-void
-Knotspec::pt_io_copy( REAL *topt, INREAL *frompt )
-{
- switch( ncoords ) {
- case 4:
- topt[3] = (REAL) frompt[3];
- case 3:
- topt[2] = (REAL) frompt[2];
- case 2:
- topt[1] = (REAL) frompt[1];
- case 1:
- topt[0] = (REAL) frompt[0];
- break;
- default: {
- for( int i = 0; i < ncoords; i++ )
- *topt++ = (REAL) *frompt++;
- }
- }
-}
-
-/*-----------------------------------------------------------------------------
- * pt_oo_copy - make internal copy of internal cntrl pt. of x coords
- *-----------------------------------------------------------------------------
- */
-
-void
-Knotspec::pt_oo_copy( REAL *topt, REAL *frompt )
-{
- switch( ncoords ) {
- case 4:
- topt[3] = frompt[3];
- case 3:
- topt[2] = frompt[2];
- case 2:
- topt[1] = frompt[1];
- case 1:
- topt[0] = frompt[0];
- break;
- default:
- memcpy( topt, frompt, ncoords * sizeof( REAL ) );
- }
-}
-
-/*-----------------------------------------------------------------------------
- * pt_oo_sum - compute affine combination of internal cntrl pts
- *-----------------------------------------------------------------------------
- */
-
-void
-Knotspec::pt_oo_sum( REAL *x, REAL *y, REAL *z, Knot a, Knot b )
-{
- switch( ncoords ) {
- case 4:
- x[3] = a * y[3] + b * z[3];
- case 3:
- x[2] = a * y[2] + b * z[2];
- case 2:
- x[1] = a * y[1] + b * z[1];
- case 1:
- x[0] = a * y[0] + b * z[0];
- break;
- default: {
- for( int i = 0; i < ncoords; i++ )
- *x++ = a * *y++ + b * *z++;
- }
- }
-}
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * trimline.c++
- *
- */
-
-#include "glimports.h"
-#include "myassert.h"
-#include "mystdio.h"
-#include "trimline.h"
-#include "backend.h"
-
-Trimline::Trimline()
-{
- size = 0; pts = 0; numverts = 0;
- tinterp = &t; binterp = &b;
-}
-
-Trimline::~Trimline()
-{
- if( pts ) delete[] pts;
-}
-
-void
-Trimline::init( TrimVertex *v )
-{
- reset();
- grow(1);
- append(v);
-}
-
-inline void
-Trimline::grow( long npts )
-{
- if( size < npts ) {
- size = 2 * npts;
- if( pts ) delete[] pts;
- pts = new TrimVertex_p[size];
- }
-}
-
-inline void
-Trimline::append( TrimVertex *v )
-{
- assert( numverts != size );
- pts[numverts++] = v;
-}
-
-void
-Trimline::init( long npts, Arc_ptr jarc, long last )
-{
- jarcl.init( jarc, 0, last );
- grow( npts + 2 );
-}
-
-inline void
-Trimline::swap()
-{
- TrimVertex *tmp=tinterp;
- tinterp=binterp;
- binterp=tmp;
-}
-
-void
-Trimline::getNextPt()
-{
- *binterp = *jarcl.getnextpt();
-}
-
-void
-Trimline::getPrevPt()
-{
- *binterp = *jarcl.getprevpt();
-}
-
-/*----------------------------------------------------------------------
- * getNextPts - make arrays of pointers to trim points on left and right
- * hulls of trim strip.
- *----------------------------------------------------------------------
- */
-void
-Trimline::getNextPts( REAL vval, Backend& backend )
-{
- reset(); swap(); append( tinterp );
- assert( tinterp->param[1] >= vval );
-
- register TrimVertex *p;
- for( p=jarcl.getnextpt() ; p->param[1] >= vval; p=jarcl.getnextpt() ) {
- append( p );
- }
-
- /* compute and copy pointer to final point on left hull */
- if( interpvert( last(), p, binterp, vval ) ) {
- binterp->nuid = p->nuid;
- backend.triangle( p, binterp, last() );
- append( binterp );
- }
- jarcl.reverse();
- (void) jarcl.getprevpt(); /* reset jarcl to proper position */
- jarcl.reverse();
-}
-
-void
-Trimline::getPrevPts( REAL vval, Backend& backend )
-{
- reset(); swap(); append( tinterp );
- assert( tinterp->param[1] >= vval );
-
- register TrimVertex *q;
- for( q=jarcl.getprevpt(); q->param[1] >= vval; q=jarcl.getprevpt() ) {
- append( q );
- }
-
- /* compute and copy pointer to final point on right hull */
- if( interpvert( q, last(), binterp, vval ) ) {
- binterp->nuid = q->nuid;
- backend.triangle( last(), binterp, q );
- append( binterp );
- }
- jarcl.reverse();
- (void) jarcl.getnextpt(); /* reset jarcl to proper position */
- jarcl.reverse();
-}
-
-void
-Trimline::getNextPts( Arc_ptr botarc )
-{
- reset(); swap(); append( tinterp );
-
-#ifndef NDEBUG
- PwlArc *lastpwl = botarc->prev->pwlArc;
- TrimVertex *lastpt1 = &lastpwl->pts[lastpwl->npts-1];
-#endif
- TrimVertex *lastpt2 = botarc->pwlArc->pts;
- register TrimVertex *p = jarcl.getnextpt();
- for( append( p ); p != lastpt2; append( p ) ) {
- assert( p != lastpt1 );
- p = jarcl.getnextpt();
- }
-}
-
-void
-Trimline::getPrevPts( Arc_ptr botarc )
-{
- reset(); swap(); append( tinterp );
-
- PwlArc *lastpwl = botarc->prev->pwlArc;
- TrimVertex *lastpt1 = &lastpwl->pts[lastpwl->npts-1];
-#ifndef NDEBUG
- TrimVertex *lastpt2 = botarc->pwlArc->pts;
-#endif
-
- register TrimVertex *q = jarcl.getprevpt();
- for( append( q ); q != lastpt1; append( q ) ) {
- assert( q != lastpt2 );
- q = jarcl.getprevpt();
- }
-}
-
-
-long
-Trimline::interpvert( TrimVertex *a, TrimVertex *b, TrimVertex *c, REAL vval )
-{
- REAL denom = a->param[1] - b->param[1];
-
- if(denom != 0) {
- if( vval == a->param[1] ) {
- c->param[0] = a->param[0];
- c->param[1] = a->param[1];
- c->nuid = a->nuid;
- return 0;
- } else if( vval == b->param[1] ) {
- c->param[0] = b->param[0];
- c->param[1] = b->param[1];
- c->nuid = b->nuid;
- return 0;
- } else {
- REAL r = (a->param[1] - vval)/denom;
- c->param[0] = a->param[0] - r * (a->param[0] - b->param[0]);
- c->param[1] = vval;
- return 1;
- }
- } else {
- c->param[0] = a->param[0];
- c->param[1] = a->param[1];
- c->nuid = a->nuid;
- return 0;
- }
-}
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * trimline.h
- *
- */
-
-#ifndef __glutrimline_h_
-#define __glutrimline_h_
-
-class Arc;
-class Backend;
-
-#include "trimvertex.h"
-#include "jarcloc.h"
-
-
-class Trimline {
-private:
- TrimVertex** pts;
- long numverts;
- long i;
- long size;
- Jarcloc jarcl;
- TrimVertex t, b;
- TrimVertex *tinterp, *binterp;
- void reset( void ) { numverts = 0; }
- inline void grow( long );
- inline void swap( void );
- inline void append( TrimVertex * );
- static long interpvert( TrimVertex *, TrimVertex *, TrimVertex *, REAL );
-
-
-
-public:
- Trimline();
- ~Trimline();
- void init( TrimVertex * );
- void init( long, Arc_ptr, long );
- void getNextPt( void );
- void getPrevPt( void );
- void getNextPts( REAL, Backend & );
- void getPrevPts( REAL, Backend & );
- void getNextPts( Arc_ptr );
- void getPrevPts( Arc_ptr );
- inline TrimVertex * next( void );
- inline TrimVertex * prev( void );
- inline TrimVertex * first( void );
- inline TrimVertex * last( void );
-};
-
-inline TrimVertex *
-Trimline::next( void )
-{
- if( i < numverts) return pts[i++]; else return 0;
-}
-
-inline TrimVertex *
-Trimline::prev( void )
-{
- if( i >= 0 ) return pts[i--]; else return 0;
-}
-
-inline TrimVertex *
-Trimline::first( void )
-{
- i = 0; return pts[i];
-}
-
-inline TrimVertex *
-Trimline::last( void )
-{
- i = numverts; return pts[--i];
-}
-#endif /* __glutrimline_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * trimregion.c++
- *
- */
-
-#include "glimports.h"
-#include "myassert.h"
-#include "mystdio.h"
-#include "trimregion.h"
-
-TrimRegion::TrimRegion( void )
-{
-}
-
-void
-TrimRegion::setDu( REAL du )
-{
- oneOverDu = 1.0/du;
-}
-
-void
-TrimRegion::init( long npts, Arc_ptr extrema )
-{
- left.init( npts, extrema, extrema->pwlArc->npts - 1 );
- left.getNextPt();
-
- right.init( npts, extrema, 0 );
- right.getPrevPt();
-}
-
-void
-TrimRegion::getPts( Arc_ptr extrema )
-{
- left.getNextPts( extrema );
- right.getPrevPts( extrema );
-}
-
-void
-TrimRegion::getPts( Backend &backend )
-{
- left.getNextPts( bot.vval, backend );
- right.getPrevPts( bot.vval, backend );
-}
-
-void
-TrimRegion::getGridExtent( void )
-{
- getGridExtent( left.last(), right.last() );
-}
-
-void
-TrimRegion::getGridExtent( TrimVertex *l, TrimVertex *r )
-{
- bot.ustart = (long) ((l->param[0] - uarray.uarray[0])*oneOverDu);
- if( l->param[0] >= uarray.uarray[bot.ustart] ) bot.ustart++;
-// if( l->param[0] > uarray.uarray[bot.ustart] ) bot.ustart++;
- assert( l->param[0] <= uarray.uarray[bot.ustart] );
- assert( l->param[0] >= uarray.uarray[bot.ustart-1] );
-
- bot.uend = (long) ((r->param[0] - uarray.uarray[0])*oneOverDu);
- if( uarray.uarray[bot.uend] >= r->param[0] ) bot.uend--;
-// if( uarray.uarray[bot.uend] > r->param[0] ) bot.uend--;
- assert( r->param[0] >= uarray.uarray[bot.uend] );
- assert( r->param[0] <= uarray.uarray[bot.uend+1] );
-}
-
-int
-TrimRegion::canTile( void )
-{
- TrimVertex *lf = left.first();
- TrimVertex *ll = left.last();
- TrimVertex *l = ( ll->param[0] > lf->param[0] ) ? ll : lf;
-
- TrimVertex *rf = right.first();
- TrimVertex *rl = right.last();
- TrimVertex *r = ( rl->param[0] < rf->param[0] ) ? rl : rf;
- return (l->param[0] <= r->param[0]) ? 1 : 0;
-}
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * trimregion.h
- *
- */
-
-#ifndef __glutrimregion_h_
-#define __glutrimregion_h_
-
-#include "trimline.h"
-#include "gridline.h"
-#include "uarray.h"
-
-class Arc;
-class Backend;
-
-class TrimRegion {
-public:
- TrimRegion();
- Trimline left;
- Trimline right;
- Gridline top;
- Gridline bot;
- Uarray uarray;
-
- void init( REAL );
- void advance( REAL, REAL, REAL );
- void setDu( REAL );
- void init( long, Arc_ptr );
- void getPts( Arc_ptr );
- void getPts( Backend & );
- void getGridExtent( TrimVertex *, TrimVertex * );
- void getGridExtent( void );
- int canTile( void );
-private:
- REAL oneOverDu;
-};
-
-inline void
-TrimRegion::init( REAL vval )
-{
- bot.vval = vval;
-}
-
-inline void
-TrimRegion::advance( REAL topVindex, REAL botVindex, REAL botVval )
-{
- top.vindex = (long) topVindex;
- bot.vindex = (long) botVindex;
- top.vval = bot.vval;
- bot.vval = botVval;
- top.ustart = bot.ustart;
- top.uend = bot.uend;
-}
-#endif /* __glutrimregion_h_ */
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * trimvertex.h
- *
- */
-
-#ifndef __glutrimvertex_h_
-#define __glutrimvertex_h_
-
-#include "types.h"
-
-/*#define USE_OPTTT*/
-
-class TrimVertex { /* a vertex on a trim curve */
-public:
- REAL param[2]; /* parametric space coords */
-#ifdef USE_OPTTT
- REAL cache_point[4]; //only when USE_OPTTT is on in slicer.c++
- REAL cache_normal[3];
-#endif
- long nuid;
-};
-
-typedef class TrimVertex *TrimVertex_p;
-
-inline REAL
-det3( TrimVertex *a, TrimVertex *b, TrimVertex *c )
-{
- return a->param[0] * (b->param[1]-c->param[1]) +
- b->param[0] * (c->param[1]-a->param[1]) +
- c->param[0] * (a->param[1]-b->param[1]);
-}
-
-#endif /* __glutrimvertex_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * trimvertexpool.c++
- *
- */
-
-#include "glimports.h"
-#include "myassert.h"
-#include "mystdio.h"
-#include "mystring.h"
-#include "trimvertex.h"
-#include "trimvertpool.h"
-#include "bufpool.h"
-
-/*----------------------------------------------------------------------------
- * TrimVertexPool::TrimVertexPool
- *----------------------------------------------------------------------------
- */
-TrimVertexPool::TrimVertexPool( void )
- : pool( sizeof(TrimVertex)*3, 32, "Threevertspool" )
-{
- // initialize array of pointers to vertex lists
- nextvlistslot = 0;
- vlistsize = INIT_VERTLISTSIZE;
- vlist = new TrimVertex_p[vlistsize];
-}
-
-/*----------------------------------------------------------------------------
- * TrimVertexPool::~TrimVertexPool
- *----------------------------------------------------------------------------
- */
-TrimVertexPool::~TrimVertexPool( void )
-{
- // free all arrays of TrimVertices vertices
- while( nextvlistslot ) {
- delete [] vlist[--nextvlistslot];
- }
-
- // reallocate space for array of pointers to vertex lists
- if( vlist ) delete[] vlist;
-}
-
-/*----------------------------------------------------------------------------
- * TrimVertexPool::clear
- *----------------------------------------------------------------------------
- */
-void
-TrimVertexPool::clear( void )
-{
- // reinitialize pool of 3 vertex arrays
- pool.clear();
-
- // free all arrays of TrimVertices vertices
- while( nextvlistslot ) {
- delete [] vlist[--nextvlistslot];
- vlist[nextvlistslot] = 0;
- }
-
- // reallocate space for array of pointers to vertex lists
- if( vlist ) delete[] vlist;
- vlist = new TrimVertex_p[vlistsize];
-}
-
-
-/*----------------------------------------------------------------------------
- * TrimVertexPool::get - allocate a vertex list
- *----------------------------------------------------------------------------
- */
-TrimVertex *
-TrimVertexPool::get( int n )
-{
- TrimVertex *v;
- if( n == 3 ) {
- v = (TrimVertex *) pool.new_buffer();
- } else {
- if( nextvlistslot == vlistsize ) {
- vlistsize *= 2;
- TrimVertex_p *nvlist = new TrimVertex_p[vlistsize];
- memcpy( nvlist, vlist, nextvlistslot * sizeof(TrimVertex_p) );
- if( vlist ) delete[] vlist;
- vlist = nvlist;
- }
- v = vlist[nextvlistslot++] = new TrimVertex[n];
- }
- return v;
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * trimvertexpool.h
- *
- */
-
-#ifndef __glutrimvertpool_h_
-#define __glutrimvertpool_h_
-
-#include "bufpool.h"
-
-class TrimVertex;
-
-#define INIT_VERTLISTSIZE 200
-
-class TrimVertexPool {
-public:
- TrimVertexPool( void );
- ~TrimVertexPool( void );
- void clear( void );
- TrimVertex * get( int );
-private:
- Pool pool;
- TrimVertex ** vlist;
- int nextvlistslot;
- int vlistsize;
-};
-#endif /* __glutrimvertpool_h_ */
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * types.h
- *
- */
-
-#ifndef __glutypes_h_
-#define __glutypes_h_
-
-//typedef double INREAL;
-#define INREAL float
-typedef float REAL;
-typedef void (*Pfvv)( void );
-typedef void (*Pfvf)( float * );
-typedef int (*cmpfunc)(const void *, const void *);
-typedef REAL Knot, *Knot_ptr;/* knot values */
-
-#endif /* __glutypes_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * uarray.c++
- *
- */
-
-#include "glimports.h"
-#include "myassert.h"
-#include "mystdio.h"
-#include "uarray.h"
-#include "arc.h"
-
-Uarray::Uarray( void )
-{
- uarray = 0;
- size = 0;
- ulines = 0;
-}
-
-Uarray::~Uarray( void )
-{
- if( uarray ) delete[] uarray;
-}
-
-long
-Uarray::init( REAL delta, Arc_ptr lo, Arc_ptr hi )
-{
- ulines = (long) ((hi->tail()[0] - lo->tail()[0])/delta) + 3;
- if( size < ulines ) {
- size = ulines * 2;
- if( uarray ) delete[] uarray;
- uarray = new REAL[size];
- assert( uarray != 0);
- }
- uarray[0] = lo->tail()[0] - delta/2.0;
- for( long i = 1 ; i != ulines; i++ )
- uarray[i] = uarray[0] + i*delta;
- return ulines;
-}
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * uarray.h
- *
- */
-
-#ifndef __gluuarray_h_
-#define __gluuarray_h_
-
-#include "types.h"
-
-class Arc;
-typedef class Arc *Arc_ptr;
-
-class Uarray {
-private:
- long size;
- long ulines;
-public:
- Uarray();
- ~Uarray();
- long init( REAL, Arc_ptr, Arc_ptr );
- REAL * uarray;
-};
-
-#endif /* __gluuarray_h_ */
+++ /dev/null
-/*
-** 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.
-*/
-
-/*
- * varray.c++
- *
- */
-
-#include "glimports.h"
-#include "myassert.h"
-#include "mystdio.h"
-#include "varray.h"
-#include "arc.h"
-#include "simplemath.h" // glu_abs()
-
-#define TINY 0.0001
-inline long sgn( REAL x )
-{
- return (x < -TINY) ? -1 : ((x > TINY) ? 1 : 0 );
-}
-
-
-Varray::Varray( void )
-{
- int i;
-
- varray = 0;
- size = 0;
- numquads = 0;
-
- for (i = 0; i < 1000; i++) {
- vval[i] = 0;
- voffset[i] = 0;
- }
-}
-
-Varray::~Varray( void )
-{
- if( varray ) delete[] varray;
-}
-
-inline void
-Varray::update( Arc_ptr arc, long dir[2], REAL val )
-{
- register long ds = sgn(arc->tail()[0] - arc->prev->tail()[0]);
- register long dt = sgn(arc->tail()[1] - arc->prev->tail()[1]);
-
- if( dir[0] != ds || dir[1] != dt ) {
- dir[0] = ds;
- dir[1] = dt;
- append( val );
- }
-}
-
-void
-Varray::grow( long guess )
-{
- if( size < guess ) {
- size = guess * 2;
- if( varray ) delete[] varray;
- varray = new REAL[size];
- assert( varray != 0 );
- }
-}
-
-long
-Varray::init( REAL delta, Arc_ptr toparc, Arc_ptr botarc )
-{
- Arc_ptr left = toparc->next;
- Arc_ptr right = toparc;
- long ldir[2], rdir[2];
-
- ldir[0] = sgn( left->tail()[0] - left->prev->tail()[0] );
- ldir[1] = sgn( left->tail()[1] - left->prev->tail()[1] );
- rdir[0] = sgn( right->tail()[0] - right->prev->tail()[0] );
- rdir[1] = sgn( right->tail()[1] - right->prev->tail()[1] );
-
- vval[0] = toparc->tail()[1];
- numquads = 0;
-
- while( 1 ) {
- switch( sgn( left->tail()[1] - right->prev->tail()[1] ) ) {
- case 1:
- left = left->next;
- update( left, ldir, left->prev->tail()[1] );
- break;
- case -1:
- right = right->prev;
- update( right, rdir, right->tail()[1] );
- break;
- case 0:
- if( glu_abs(left->tail()[1] - botarc->tail()[1]) < TINY) goto end;
- if( glu_abs(left->tail()[0]-right->prev->tail()[0]) < TINY &&
- glu_abs(left->tail()[1]-right->prev->tail()[1]) < TINY) goto end;
- left = left->next;
- break;
- }
- }
-
-end:
- append( botarc->tail()[1] );
-
- grow( ((long) ((vval[0] - vval[numquads])/delta)) + numquads + 2 );
-
- long i, index = 0;
- for( i=0; i<numquads; i++ ) {
- voffset[i] = index;
- varray[index++] = vval[i];
- REAL dist = vval[i] - vval[i+1];
- if( dist > delta ) {
- long steps = ((long) (dist/delta)) +1;
- float deltav = - dist / (REAL) steps;
- for( long j=1; j<steps; j++ )
- varray[index++] = vval[i] + j * deltav;
- }
- }
- voffset[i] = index;
- varray[index] = vval[i];
- return index;
-}
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * varray.h
- *
- */
-
-#ifndef __gluvarray_h_
-#define __gluvarray_h_
-
-#include "types.h"
-
-class Arc;
-
-class Varray {
-public:
- Varray();
- ~Varray();
- long init( REAL, Arc *, Arc * );
- REAL * varray;
- REAL vval[1000];
- long voffset[1000];
- long numquads;
-
-private:
- long size;
- inline void update( Arc *, long[2], REAL );
- void grow( long );
- inline void append( REAL );
-};
-
-inline void
-Varray::append( REAL v )
-{
- if( v != vval[numquads] )
- vval[++numquads] = v;
-}
-
-
-#endif /* __gluvarray_h_ */
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-#ifndef _DEFINITIONS_H
-#define _DEFINITIONS_H
-
-typedef float Real;
-typedef int Int;
-typedef Real Real2[2];
-
-#endif
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-#include "glimports.h"
-#include "zlassert.h"
-
-#include "quicksort.h"
-#include "directedLine.h"
-#include "polyDBG.h"
-
-#ifdef __WATCOMC__
-#pragma warning 726 10
-#endif
-
-//we must return the newLine
-directedLine* directedLine::deleteChain(directedLine* begin, directedLine* end)
-{
- if(begin->head()[0] == end->tail()[0] &&
- begin->head()[1] == end->tail()[1]
- )
- {
- directedLine *ret = begin->prev;
- begin->prev->next = end->next;
- end->next->prev = begin->prev;
- delete begin->sline;
- delete end->sline;
- delete begin;
- delete end;
-
- return ret;
- }
-
- directedLine* newLine;
- sampledLine* sline = new sampledLine(begin->head(), end->tail());
- newLine = new directedLine(INCREASING, sline);
- directedLine *p = begin->prev;
- directedLine *n = end->next;
- p->next = newLine;
- n->prev = newLine;
- newLine->prev = p;
- newLine->next = n;
-
- delete begin->sline;
- delete end->sline;
- delete begin;
- delete end;
- return newLine;
-}
-
-
-void directedLine::deleteSingleLine(directedLine* dline)
-{
- //make sure that dline->prev->tail is the same as
- //dline->next->head. This is for numerical erros.
- //for example, if we delete a line which is almost degeneate
- //within (epsilon), then we want to make that the polygon after deletion
- //is still a valid polygon
-
- dline->next->head()[0] = dline->prev->tail()[0];
- dline->next->head()[1] = dline->prev->tail()[1];
-
- dline->prev->next = dline->next;
- dline->next->prev = dline->prev;
-
- delete dline;
-
-}
-
-static Int myequal(Real a[2], Real b[2])
-{
- /*
- if(a[0]==b[0] && a[1] == b[1])
- return 1;
- else
- return 0;
- */
-
-
- if(fabs(a[0]-b[0]) < 0.00001 &&
- fabs(a[1]-b[1]) < 0.00001)
- return 1;
- else
- return 0;
-
-}
-
-directedLine* directedLine::deleteDegenerateLines()
-{
- //if there is only one edge or two edges, don't do anything
- if(this->next == this)
- return this;
- if(this->next == this->prev)
- return this;
-
- //find a nondegenerate line
- directedLine* temp;
- directedLine* first = NULL;
- if(! myequal(head(), tail()))
- /*
- if(head()[0] != tail()[0] ||
- head()[1] != tail()[1])
- */
- first = this;
- else
- {
- for(temp = this->next; temp != this; temp = temp->next)
- {
- /*
- if(temp->head()[0] != temp->tail()[0] ||
- temp->head()[1] != temp->tail()[1])
- */
- if(! myequal(temp->head(), temp->tail()))
- {
- first = temp;
- break;
- }
-
- }
- }
-
- //if there are no non-degenerate lines, then we simply return NULL.
- if(first == NULL)
- {
- deleteSinglePolygonWithSline();
- return NULL;
- }
-
- directedLine* tempNext = NULL;
- for(temp =first->next; temp != first; temp = tempNext)
- {
- tempNext = temp->getNext();
-/*
- if(temp->head()[0] == temp->tail()[0] &&
- temp->head()[1] == temp->tail()[1])
-*/
-
- if(myequal(temp->head(), temp->tail()))
- deleteSingleLine(temp);
- }
- return first;
-}
-
-directedLine* directedLine::deleteDegenerateLinesAllPolygons()
-{
- directedLine* temp;
- directedLine *tempNext = NULL;
- directedLine* ret= NULL;
- directedLine* retEnd = NULL;
- for(temp=this; temp != NULL; temp = tempNext)
- {
- tempNext = temp->nextPolygon;
- temp->nextPolygon = NULL;
- if(ret == NULL)
- {
- ret = retEnd = temp->deleteDegenerateLines();
-
- }
- else
- {
- directedLine *newPolygon = temp->deleteDegenerateLines();
- if(newPolygon != NULL)
- {
- retEnd->nextPolygon = temp->deleteDegenerateLines();
- retEnd = retEnd->nextPolygon;
- }
- }
- }
- return ret;
-}
-
-directedLine* directedLine::cutIntersectionAllPoly(int &cutOccur)
-{
- directedLine* temp;
- directedLine *tempNext = NULL;
- directedLine* ret= NULL;
- directedLine* retEnd = NULL;
- cutOccur = 0;
- for(temp=this; temp != NULL; temp = tempNext)
- {
- int eachCutOccur=0;
- tempNext = temp->nextPolygon;
- temp->nextPolygon = NULL;
- if(ret == NULL)
- {
-
- ret = retEnd = DBG_cutIntersectionPoly(temp, eachCutOccur);
- if(eachCutOccur)
- cutOccur = 1;
- }
- else
- {
-
- retEnd->nextPolygon = DBG_cutIntersectionPoly(temp, eachCutOccur);
- retEnd = retEnd->nextPolygon;
- if(eachCutOccur)
- cutOccur = 1;
- }
- }
- return ret;
-}
-
-
-void directedLine::deleteSinglePolygonWithSline()
-{
- directedLine *temp, *tempNext;
- prev->next = NULL;
- for(temp=this; temp != NULL; temp = tempNext)
- {
- tempNext = temp->next;
- delete temp->sline;
- delete temp;
- }
-}
-
-void directedLine::deletePolygonListWithSline()
-{
- directedLine *temp, *tempNext;
- for(temp=this; temp != NULL; temp=tempNext)
- {
- tempNext = temp->nextPolygon;
- temp->deleteSinglePolygonWithSline();
- }
-}
-
-void directedLine::deleteSinglePolygon()
-{
- directedLine *temp, *tempNext;
- prev->next = NULL;
- for(temp=this; temp != NULL; temp = tempNext)
- {
- tempNext = temp->next;
- delete temp;
- }
-}
-
-void directedLine::deletePolygonList()
-{
- directedLine *temp, *tempNext;
- for(temp=this; temp != NULL; temp=tempNext)
- {
- tempNext = temp->nextPolygon;
- temp->deleteSinglePolygon();
- }
-}
-
-
-/*a loop by itself*/
-directedLine::directedLine(short dir, sampledLine* sl)
-{
- direction = dir;
- sline = sl;
- next = this;
- prev = this;
- nextPolygon = NULL;
-// prevPolygon = NULL;
- rootBit = 0;/*important to initilzae to 0 meaning not root yet*/
-
- rootLink = NULL;
-
-}
-
-void directedLine::init(short dir, sampledLine* sl)
-{
- direction = dir;
- sline = sl;
-}
-
-directedLine::directedLine()
-{
- next = this;
- prev = this;
- nextPolygon = NULL;
- rootBit = 0;/*important to initilzae to 0 meaning not root yet*/
- rootLink = NULL;
- direction = INCREASING;
- sline = NULL;
-}
-
-directedLine::~directedLine()
-{
-}
-
-Real* directedLine::head()
-{
-
- return (direction==INCREASING)? (sline->get_points())[0] : (sline->get_points())[sline->get_npoints()-1];
-}
-
-/*inline*/ Real* directedLine::getVertex(Int i)
-{
- return (direction==INCREASING)? (sline->get_points())[i] : (sline->get_points())[sline->get_npoints() - 1 -i];
-}
-
-Real* directedLine::tail()
-{
- return (direction==DECREASING)? (sline->get_points())[0] : (sline->get_points())[sline->get_npoints()-1];
-}
-
- /*insert a new line between prev and this*/
-void directedLine::insert(directedLine* nl)
-{
- nl->next = this;
- nl->prev = prev;
- prev->next = nl;
- prev = nl;
- nl->rootLink = this; /*assuming that 'this' is the root!!!*/
-}
-
-Int directedLine::numEdges()
-{
- Int ret=0;
- directedLine* temp;
- if(next == this) return 1;
-
- ret = 1;
- for(temp = next; temp != this; temp = temp->next)
- ret++;
- return ret;
-}
-
-Int directedLine::numEdgesAllPolygons()
-{
- Int ret=0;
- directedLine* temp;
- for(temp=this; temp!= NULL; temp=temp->nextPolygon)
- {
- ret += temp->numEdges();
- }
- return ret;
-}
-
-/*return 1 if the double linked list forms a polygon.
- */
-short directedLine::isPolygon()
-{
- directedLine* temp;
-
- /*a polygon contains at least 3 edges*/
- if(numEdges() <=2) return 0;
-
- /*check this edge*/
- if(! isConnected()) return 0;
-
- /*check all other edges*/
- for(temp=next; temp != this; temp = temp->next){
- if(!isConnected()) return 0;
- }
- return 1;
-}
-
-/*check if the head of this edge is connected to
- *the tail of the prev
- */
-short directedLine::isConnected()
-{
- if( (head()[0] == prev->tail()[0]) && (head()[1] == prev->tail()[1]))
- return 1;
- else
- return 0;
-}
-
-Int compV2InY(Real A[2], Real B[2])
-{
- if(A[1] < B[1]) return -1;
- if(A[1] == B[1] && A[0] < B[0]) return -1;
- if(A[1] == B[1] && A[0] == B[0]) return 0;
- return 1;
-}
-
-Int compV2InX(Real A[2], Real B[2])
-{
- if(A[0] < B[0]) return -1;
- if(A[0] == B[0] && A[1] < B[1]) return -1;
- if(A[0] == B[0] && A[1] == B[1]) return 0;
- return 1;
-}
-
-/*compare two vertices NOT lines!
- *A vertex is the head of a directed line.
- *(x_1, y_1) <= (x_2, y_2) if
- *either y_1 < y_2
- *or y_1 == y_2 && x_1 < x_2.
- *return -1 if this->head() <= nl->head(),
- *return 1 otherwise
- */
-Int directedLine::compInY(directedLine* nl)
-{
- if(head()[1] < nl->head()[1]) return -1;
- if(head()[1] == nl->head()[1] && head()[0] < nl->head()[0]) return -1;
- return 1;
-}
-
-/*compare two vertices NOT lines!
- *A vertex is the head of a directed line.
- *(x_1, y_1) <= (x_2, y_2) if
- *either x_1 < x_2
- *or x_1 == x_2 && y_1 < y_2.
- *return -1 if this->head() <= nl->head(),
- *return 1 otherwise
- */
-Int directedLine::compInX(directedLine* nl)
-{
- if(head()[0] < nl->head()[0]) return -1;
- if(head()[0] == nl->head()[0] && head()[1] < nl->head()[1]) return -1;
- return 1;
-}
-
-/*used by sort precedures
- */
-static Int compInY2(directedLine* v1, directedLine* v2)
-{
- return v1->compInY(v2);
-}
-#ifdef NOT_USED
-static Int compInX(directedLine* v1, directedLine* v2)
-{
- return v1->compInX(v2);
-}
-#endif
-
-/*sort all the vertices NOT the lines!
- *a vertex is the head of a directed line
- */
-directedLine** directedLine::sortAllPolygons()
-{
- Int total_num_edges = 0;
- directedLine** array = toArrayAllPolygons(total_num_edges);
- quicksort( (void**)array, 0, total_num_edges-1, (Int (*)(void *, void *)) compInY2);
-
- return array;
-}
-
-void directedLine::printSingle()
-{
- if(direction == INCREASING)
- printf("direction is INCREASING\n");
- else
- printf("direction is DECREASING\n");
- printf("head=%f,%f)\n", head()[0], head()[1]);
- sline->print();
-}
-
-/*print one polygon*/
-void directedLine::printList()
-{
- directedLine* temp;
- printSingle();
- for(temp = next; temp!=this; temp=temp->next)
- temp->printSingle();
-}
-
-/*print all the polygons*/
-void directedLine::printAllPolygons()
-{
- directedLine *temp;
- for(temp = this; temp!=NULL; temp = temp->nextPolygon)
- {
- printf("polygon:\n");
- temp->printList();
- }
-}
-
-/*insert this polygon into the head of the old polygon List*/
-directedLine* directedLine::insertPolygon(directedLine* oldList)
-{
- /*this polygon is a root*/
- setRootBit();
- if(oldList == NULL) return this;
- nextPolygon = oldList;
-/* oldList->prevPolygon = this;*/
- return this;
-}
-
-/*cutoff means delete. but we don't deallocate any space,
- *so we use cutoff instead of delete
- */
-directedLine* directedLine::cutoffPolygon(directedLine *p)
-{
- directedLine* temp;
- directedLine* prev_polygon = NULL;
- if(p == NULL) return this;
-
- for(temp=this; temp != p; temp = temp->nextPolygon)
- {
- if(temp == NULL)
- {
- fprintf(stderr, "in cutoffPolygon, not found\n");
- exit(1);
- }
- prev_polygon = temp;
- }
-
-/* prev_polygon = p->prevPolygon;*/
-
- p->resetRootBit();
- if(prev_polygon == NULL) /*this is the one to cutoff*/
- return nextPolygon;
- else {
- prev_polygon->nextPolygon = p->nextPolygon;
- return this;
- }
-}
-
-Int directedLine::numPolygons()
-{
- if(nextPolygon == NULL) return 1;
- else return 1+nextPolygon->numPolygons();
-}
-
-
-/*let array[index ...] denote
- *all the edges in this polygon
- *return the next available index of array.
- */
-Int directedLine::toArraySinglePolygon(directedLine** array, Int index)
-{
- directedLine *temp;
- array[index++] = this;
- for(temp = next; temp != this; temp = temp->next)
- {
- array[index++] = temp;
- }
- return index;
-}
-
-/*the space is allocated. The caller is responsible for
- *deallocate the space.
- *total_num_edges is set to be the total number of edges of all polygons
- */
-directedLine** directedLine::toArrayAllPolygons(Int& total_num_edges)
-{
- total_num_edges=numEdgesAllPolygons();
- directedLine** ret = (directedLine**) malloc(sizeof(directedLine*) * total_num_edges);
- assert(ret);
-
- directedLine *temp;
- Int index = 0;
- for(temp=this; temp != NULL; temp=temp->nextPolygon) {
- index = temp->toArraySinglePolygon(ret, index);
- }
- return ret;
-}
-
-/*assume the polygon is a simple polygon, return
- *the area enclosed by it.
- *if thee order is counterclock wise, the area is positive.
- */
-Real directedLine::polyArea()
-{
- directedLine* temp;
- Real ret=0.0;
- Real x1,y1,x2,y2;
- x1 = this->head()[0];
- y1 = this->head()[1];
- x2 = this->next->head()[0];
- y2 = this->next->head()[1];
- ret = -(x2*y1-x1*y2);
- for(temp=this->next; temp!=this; temp = temp->next)
- {
- x1 = temp->head()[0];
- y1 = temp->head()[1];
- x2 = temp->next->head()[0];
- y2 = temp->next->head()[1];
- ret += -( x2*y1-x1*y2);
- }
- return Real(0.5)*ret;
-}
-
-/*******************split or combine polygons begin********************/
-/*conect a diagonal of a single simple polygon or two simple polygons.
- *If the two vertices v1 (head) and v2 (head) are in the same simple polygon,
- *then we actually split the simple polygon into two polygons.
- *If instead two vertices velong to two difference polygons,
- *then we combine the two polygons into one polygon.
- *It is upto the caller to decide whether this is a split or a
- *combination.
- *
- *Case Split:
- *split a single simple polygon into two simple polygons by
- *connecting a diagonal (two vertices).
- *v1, v2: the two vertices are the head() of the two directedLines.
- * this routine generates one new sampledLine which is returned in
- *generatedLine,
- *and it generates two directedLines returned in ret_p1 and ret_p2.
- *ret_p1 and ret_p2 are used as the entry to the two new polygons.
- *Notice the caller should not deallocate the space of v2 and v2 after
- *calling this function, since all of the edges are connected to
- *ret_p1 or ret_p2.
- *
- *combine:
- *combine two simpolygons into one by connecting one diagonal.
- *the returned polygon is returned in ret_p1.
- */
-/*ARGSUSED*/
-void directedLine::connectDiagonal(directedLine* v1, directedLine* v2,
- directedLine** ret_p1,
- directedLine** ret_p2,
- sampledLine** generatedLine,
- directedLine* polygonList )
-{
- sampledLine *nsline = new sampledLine(2);
-
-
-
- nsline->setPoint(0, v1->head());
- nsline->setPoint(1, v2->head());
-
-
-
- /*the increasing line is from v1 head to v2 head*/
- directedLine* newLineInc = new directedLine(INCREASING, nsline);
-
-
-
- directedLine* newLineDec = new directedLine(DECREASING, nsline);
-
-
- directedLine* v1Prev = v1->prev;
- directedLine* v2Prev = v2->prev;
-
- v1 ->prev = newLineDec;
- v2Prev ->next = newLineDec;
- newLineDec->next = v1;
- newLineDec->prev = v2Prev;
-
- v2 ->prev = newLineInc;
- v1Prev ->next = newLineInc;
- newLineInc->next = v2;
- newLineInc->prev = v1Prev;
-
- *ret_p1 = newLineDec;
- *ret_p2 = newLineInc;
- *generatedLine = nsline;
-}
-
-//see the function connectDiangle
-/*ARGSUSED*/
-void directedLine::connectDiagonal_2slines(directedLine* v1, directedLine* v2,
- directedLine** ret_p1,
- directedLine** ret_p2,
- directedLine* polygonList )
-{
- sampledLine *nsline = new sampledLine(2);
- sampledLine *nsline2 = new sampledLine(2);
-
- nsline->setPoint(0, v1->head());
- nsline->setPoint(1, v2->head());
- nsline2->setPoint(0, v1->head());
- nsline2->setPoint(1, v2->head());
-
- /*the increasing line is from v1 head to v2 head*/
- directedLine* newLineInc = new directedLine(INCREASING, nsline);
-
- directedLine* newLineDec = new directedLine(DECREASING, nsline2);
-
- directedLine* v1Prev = v1->prev;
- directedLine* v2Prev = v2->prev;
-
- v1 ->prev = newLineDec;
- v2Prev ->next = newLineDec;
- newLineDec->next = v1;
- newLineDec->prev = v2Prev;
-
- v2 ->prev = newLineInc;
- v1Prev ->next = newLineInc;
- newLineInc->next = v2;
- newLineInc->prev = v1Prev;
-
- *ret_p1 = newLineDec;
- *ret_p2 = newLineInc;
-
-}
-
-Int directedLine::samePolygon(directedLine* v1, directedLine* v2)
-{
- if(v1 == v2) return 1;
- directedLine *temp;
- for(temp = v1->next; temp != v1; temp = temp->next)
- {
- if(temp == v2) return 1;
- }
- return 0;
-}
-
-directedLine* directedLine::findRoot()
-{
- if(rootBit) return this;
- directedLine* temp;
- for(temp = next; temp != this; temp = temp->next)
- if(temp -> rootBit ) return temp;
- return NULL; /*should not happen*/
-}
-
-directedLine* directedLine::rootLinkFindRoot()
-{
- directedLine* tempRoot;
- directedLine* tempLink;
- tempRoot = this;
- tempLink = rootLink;
- while(tempLink != NULL){
- tempRoot = tempLink;
- tempLink = tempRoot->rootLink;
- }
- return tempRoot;
-}
-
-/*******************split or combine polygons end********************/
-
-/*****************IO stuff begin*******************/
-
-/*format:
- *#polygons
- * #vertices
- * vertices
- * #vertices
- * vertices
- *...
- */
-void directedLine::writeAllPolygons(char* filename)
-{
- FILE* fp = fopen(filename, "w");
- assert(fp);
- Int nPolygons = numPolygons();
- directedLine *root;
- fprintf(fp, "%i\n", nPolygons);
- for(root = this; root != NULL; root = root->nextPolygon)
- {
- directedLine *temp;
- Int npoints=0;
- npoints = root->get_npoints()-1;
- for(temp = root->next; temp != root; temp=temp->next)
- npoints += temp->get_npoints()-1;
- fprintf(fp, "%i\n", npoints/*root->numEdges()*/);
-
-
- for(Int i=0; i<root->get_npoints()-1; i++){
- fprintf(fp, "%f ", root->getVertex(i)[0]);
- fprintf(fp, "%f ", root->getVertex(i)[1]);
- }
-
- for(temp=root->next; temp != root; temp = temp->next)
- {
- for(Int i=0; i<temp->get_npoints()-1; i++){
-
- fprintf(fp, "%f ", temp->getVertex(i)[0]);
- fprintf(fp, "%f ", temp->getVertex(i)[1]);
- }
- fprintf(fp,"\n");
- }
- fprintf(fp, "\n");
- }
- fclose(fp);
-}
-
-directedLine* readAllPolygons(char* filename)
-{
- Int i,j;
- FILE* fp = fopen(filename, "r");
- Int nPolygons;
- int result;
-
- assert(fp);
- result = fscanf(fp, "%i", &nPolygons);
- assert(result != EOF);
- directedLine *ret = NULL;
-
- for(i=0; i<nPolygons; i++)
- {
- Int nEdges;
- result = fscanf(fp, "%i", &nEdges);
- assert(result != EOF);
- Real vert[2][2] = { { 0 } };
- Real VV[2][2];
- /*the first two vertices*/
- result = fscanf(fp, "%f", &(vert[0][0]));
- assert(result != EOF);
- result = fscanf(fp, "%f", &(vert[0][1]));
- assert(result != EOF);
- result = fscanf(fp, "%f", &(vert[1][0]));
- assert(result != EOF);
- result = fscanf(fp, "%f", &(vert[1][1]));
- assert(result != EOF);
- VV[1][0] = vert[0][0];
- VV[1][1] = vert[0][1];
- sampledLine *sLine = new sampledLine(2, vert);
- directedLine *thisPoly = new directedLine(INCREASING, sLine);
-thisPoly->rootLinkSet(NULL);
-
- directedLine *dLine;
- for(j=2; j<nEdges; j++)
- {
- vert[0][0]=vert[1][0];
- vert[0][1]=vert[1][1];
- result = fscanf(fp, "%f", &(vert[1][0]));
- assert(result != EOF);
- result = fscanf(fp, "%f", &(vert[1][1]));
- assert(result != EOF);
- sLine = new sampledLine(2,vert);
- dLine = new directedLine(INCREASING, sLine);
-dLine->rootLinkSet(thisPoly);
- thisPoly->insert(dLine);
- }
-
- VV[0][0]=vert[1][0];
- VV[0][1]=vert[1][1];
- sLine = new sampledLine(2,VV);
- dLine = new directedLine(INCREASING, sLine);
-dLine->rootLinkSet(thisPoly);
- thisPoly->insert(dLine);
-
- ret = thisPoly->insertPolygon(ret);
- }
- fclose(fp);
- return ret;
-}
-
-
-
-
-
-
-
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-#ifndef _DIRECTEDLINE_H
-#define _DIRECTEDLINE_H
-
-#include "definitions.h"
-#include "sampledLine.h"
-
-enum {INCREASING, DECREASING};
-
-class directedLine {
- short direction; /*INCREASING or DECREASING*/
- sampledLine* sline;
- directedLine* next; /*double linked list*/
- directedLine* prev; /*double linked list*/
-
- /*in case we need a list of polygons each
- *consisting of a double linked list
- */
- directedLine* nextPolygon;
-
- /*optimization make cutoff polygon faster*/
-/* directedLine* prevPolygon;*/
-
- Int rootBit; /*1 if this is a root of the polygon, set by setRootBit*/
- /*and reset by resetRootBit()*/
-
- directedLine* rootLink; /*fast root-finding*/
-
-
-
-public:
- directedLine(short dir, sampledLine* sl);
- directedLine();
- ~directedLine();
-
- void init(short dir, sampledLine* sl);
-
- Real* head(); /*points[0] if INCREASING, points[n-1] otherwise*/
- Real* tail(); /*points[n-1] if INCREASING, points[0] otherwise*/
- Real* getVertex(Int i); /*points[i] if INCREASING, points[n-1-i] otherwise*/
- Int get_npoints() {return sline->get_npoints();}
- directedLine* getPrev() {return prev;}
- directedLine* getNext() {return next;}
- directedLine* getNextPolygon() {return nextPolygon;}
- sampledLine* getSampledLine() {return sline;}
-
- short getDirection(){return direction;}
- void putDirection(short dir) {direction = dir;}
- void putPrev(directedLine *p) {prev = p;}
- void putNext(directedLine *p) {next = p;}
-
- /*insert a new line between prev and this*/
- void insert(directedLine* nl);
-
- /*delete all the polygons following the link: nextPolygon.
- *notice that sampledLine is not deleted. The caller is
- *responsible for that
- */
- void deletePolygonList();
- void deleteSinglePolygon();
-
- void deleteSinglePolygonWithSline(); //also delete sanmpled line
- void deletePolygonListWithSline(); //also delete sanmpled line
-
- void deleteSingleLine(directedLine* dline);
- directedLine* deleteDegenerateLines();
- directedLine* deleteDegenerateLinesAllPolygons();
- directedLine* cutIntersectionAllPoly(int& cutOccur);
-
- /*check to see if the list forms a closed polygon
- *return 1 if yes
- */
- short isPolygon();
-
- Int compInY(directedLine* nl);
- Int compInX(directedLine* nl);
-
- /*return an array of pointers.
- *the
- */
- directedLine** sortAllPolygons();
-
- Int numEdges();
- Int numEdgesAllPolygons();
- Int numPolygons();
-
- /*check if the head of this edge is connected to
- *the tail of the prev
- */
- short isConnected();
-
- Real polyArea();
-
- void printSingle();
- void printList();
- void printAllPolygons();
- void writeAllPolygons(char* filename);
-
-
- /*insert a polygon: using nextPolygon*/
- directedLine* insertPolygon(directedLine* newpolygon);
- directedLine* cutoffPolygon(directedLine *p);
-
- Int toArraySinglePolygon(directedLine** array, Int index);
- directedLine** toArrayAllPolygons(Int& total_num_edges);
-
- void connectDiagonal(directedLine* v1, directedLine* v2,
- directedLine** ret_p1,
- directedLine** ret_p2,
- sampledLine** generatedLine, directedLine* list);
-
- /*generate two slines
- */
- void connectDiagonal_2slines(directedLine* v1, directedLine* v2,
- directedLine** ret_p1,
- directedLine** ret_p2,
- directedLine* list);
-
- Int samePolygon(directedLine* v1, directedLine* v2);
- void setRootBit() {rootBit = 1;}
- void resetRootBit() {rootBit = 0;}
- directedLine* findRoot();
-
- void rootLinkSet(directedLine* r) {rootLink = r;}
- directedLine* rootLinkFindRoot();
-
- //the chain from begin to end is deleted (the space is deallocated)
- //and a new edge(which connectes the head of begin and the tail of end)
- // is inserted. The new polygon is returned.
- //notice that "this" is arbitrary
- directedLine* deleteChain(directedLine* begin, directedLine* end);
-};
-
-directedLine* readAllPolygons(char* filename);
-
-extern Int compV2InY(Real A[2], Real B[2]);
-extern Int compV2InX(Real A[2], Real B[2]);
-
-#endif
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * glimports.h
- *
- */
-
-#ifndef __gluimports_h_
-#define __gluimports_h_
-
-#include "mystdlib.h"
-#include "mystdio.h"
-
-#endif /* __gluimports_h_ */
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include "gluos.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <GL/gl.h>
-#include "zlassert.h"
-#include "gridWrap.h"
-
-
-/*******************grid structure****************************/
-void gridWrap::print()
-{
- printf("n_ulines = %i\n", n_ulines);
- printf("n_vlines = %i\n", n_vlines);
- printf("u_min=%f, umax=%f, vmin=%f, vmax=%f\n", u_min, u_max, v_min, v_max);
-}
-
-gridWrap::gridWrap(Int nUlines, Real* uvals,
- Int nVlines, Real* vvals)
-{
- assert(nUlines>=2);
- assert(nVlines>=2);
-
- is_uniform = 0;
- n_ulines = nUlines;
- n_vlines = nVlines;
- u_min = uvals[0];
- u_max = uvals[nUlines-1];
- v_min = vvals[0];
- v_max = vvals[nVlines-1];
- u_values = (Real*) malloc(sizeof(Real) * n_ulines);
- assert(u_values);
- v_values = (Real*) malloc(sizeof(Real) * n_vlines);
- assert(v_values);
-
- Int i;
- for(i=0; i<n_ulines; i++)
- u_values[i] = uvals[i];
- for(i=0; i<n_vlines; i++)
- v_values[i] = vvals[i];
-}
-
-gridWrap::gridWrap(Int nUlines, Int nVlines,
- Real uMin, Real uMax,
- Real vMin, Real vMax
- )
-{
- is_uniform = 1;
- n_ulines = nUlines;
- n_vlines = nVlines;
- u_min = uMin;
- u_max = uMax;
- v_min = vMin;
- v_max = vMax;
- u_values = (Real*) malloc(sizeof(Real) * n_ulines);
- assert(u_values);
- v_values = (Real*) malloc(sizeof(Real) * n_vlines);
- assert(v_values);
-
- Int i;
- assert(nUlines>=2);
- assert(nVlines>=2);
- Real du = (uMax-uMin)/(nUlines-1);
- Real dv = (vMax-vMin)/(nVlines-1);
-
- float tempu=uMin;
- u_values[0] = tempu;
- for(i=1; i<nUlines; i++)
- {
- tempu += du;
- u_values[i] = tempu;
- }
- u_values[nUlines-1] = uMax;
-
- float tempv=vMin;
- v_values[0] = tempv;
- for(i=1; i<nVlines; i++)
- {
- tempv += dv;
- v_values[i] = tempv;
- }
- v_values[nVlines-1] = vMax;
-}
-
-gridWrap::~gridWrap()
-{
- free(u_values);
- free(v_values);
-}
-
-void gridWrap::draw()
-{
- int i,j;
- glBegin(GL_POINTS);
- for(i=0; i<n_ulines; i++)
- for(j=0; j<n_vlines; j++)
- glVertex2f(get_u_value(i), get_v_value(j));
- glEnd();
-}
-
-void gridWrap::outputFanWithPoint(Int v, Int uleft, Int uright, Real vert[2], primStream* pStream)
-{
- Int i;
- if(uleft >= uright)
- return; //no triangles to output.
-
- pStream->begin();
- pStream->insert(vert);
-
- assert(vert[1] != v_values[v]); //don't output degenerate triangles
-
- if(vert[1] > v_values[v]) //vertex is above this grid line: notice the orientation
- {
- for(i=uleft; i<=uright; i++)
- pStream->insert(u_values[i], v_values[v]);
- }
- else //vertex is below the grid line
- {
- for(i=uright; i>= uleft; i--)
- pStream->insert(u_values[i], v_values[v]);
- }
-
- pStream->end(PRIMITIVE_STREAM_FAN);
-}
-
-
-
-/*each chain stores a number of consecutive
- *V-lines within a grid.
- *There is one grid vertex on each V-line.
- * The total number of V-lines is:
- * nVlines.
- * with respect to the grid, the index of the first V-line is
- * firstVlineIndex.
- * So with respect to the grid, the index of the ith V-line is
- * firstVlineIndex-i.
- * the grid-index of the uline at the ith vline (recall that each vline has one grid point)
- * is ulineIndices[i]. The u_value is cached in ulineValues[i], that is,
- * ulineValues[i] = grid->get_u_value(ulineIndices[i])
- */
-gridBoundaryChain::gridBoundaryChain(
- gridWrap* gr,
- Int first_vline_index,
- Int n_vlines,
- Int* uline_indices,
- Int* inner_indices
- )
-: grid(gr), firstVlineIndex(first_vline_index), nVlines(n_vlines)
-{
- ulineIndices = (Int*) malloc(sizeof(Int) * n_vlines);
- assert(ulineIndices);
-
- innerIndices = (Int*) malloc(sizeof(Int) * n_vlines);
- assert(innerIndices);
-
- vertices = (Real2*) malloc(sizeof(Real2) * n_vlines);
- assert(vertices);
-
-
-
- Int i;
- for(i=0; i<n_vlines; i++){
- ulineIndices[i] = uline_indices[i];
- innerIndices[i] = inner_indices[i];
- }
-
- for(i=0; i<n_vlines; i++){
- vertices[i][0] = gr->get_u_value(ulineIndices[i]);
- vertices[i][1] = gr->get_v_value(first_vline_index-i);
- }
-}
-
-void gridBoundaryChain::draw()
-{
- Int i;
- glBegin(GL_LINE_STRIP);
- for(i=0; i<nVlines; i++)
- {
- glVertex2fv(vertices[i]);
- }
- glEnd();
-}
-
-void gridBoundaryChain::drawInner()
-{
- Int i;
- for(i=1; i<nVlines; i++)
- {
- glBegin(GL_LINE_STRIP);
- glVertex2f(grid->get_u_value(innerIndices[i]), get_v_value(i-1) );
- glVertex2f(grid->get_u_value(innerIndices[i]), get_v_value(i) );
- glEnd();
- }
-}
-
-Int gridBoundaryChain::lookfor(Real v, Int i1, Int i2)
-{
- Int mid;
- while(i1 < i2-1)
- {
- mid = (i1+i2)/2;
- if(v > vertices[mid][1])
- {
- i2 = mid;
- }
- else
- i1 = mid;
- }
- return i1;
-}
-
-/*output the fan of the right end between grid line i-1 and grid line i*/
-void gridBoundaryChain::rightEndFan(Int i, primStream* pStream)
-{
- Int j;
- if(getUlineIndex(i) > getUlineIndex(i-1))
- {
- pStream->begin();
- pStream->insert(get_vertex(i-1));
- for(j=getUlineIndex(i-1); j<= getUlineIndex(i); j++)
- pStream->insert(grid->get_u_value(j), get_v_value(i));
- pStream->end(PRIMITIVE_STREAM_FAN);
- }
- else if(getUlineIndex(i) < getUlineIndex(i-1))
- {
- pStream->begin();
- pStream->insert(get_vertex(i));
- for(j=getUlineIndex(i-1); j>= getUlineIndex(i); j--)
- pStream->insert(grid->get_u_value(j), get_v_value(i-1));
- pStream->end(PRIMITIVE_STREAM_FAN);
- }
- //otherside, the two are equal, so there is no fan to output
-}
-
-
-/*output the fan of the left end between grid line i-1 and grid line i*/
-void gridBoundaryChain::leftEndFan(Int i, primStream* pStream)
-{
- Int j;
- if(getUlineIndex(i) < getUlineIndex(i-1))
- {
- pStream->begin();
- pStream->insert(get_vertex(i-1));
- for(j=getUlineIndex(i); j<= getUlineIndex(i-1); j++)
- pStream->insert(grid->get_u_value(j), get_v_value(i));
- pStream->end(PRIMITIVE_STREAM_FAN);
- }
- else if(getUlineIndex(i) > getUlineIndex(i-1))
- {
- pStream->begin();
- pStream->insert(get_vertex(i));
- for(j=getUlineIndex(i); j>= getUlineIndex(i-1); j--)
- pStream->insert(grid->get_u_value(j), get_v_value(i-1));
- pStream->end(PRIMITIVE_STREAM_FAN);
- }
- /*otherwisem, the two are equal, so there is no fan to outout*/
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-#ifndef _GRIDWRAP_H
-#define _GRIDWRAP_H
-
-#include <stdio.h>
-#include "definitions.h"
-
-#include "primitiveStream.h"
-#include "zlassert.h"
-
-class gridWrap{
- Int n_ulines;
- Int n_vlines;
- Real u_min, u_max;
- Real v_min, v_max;
-
- /*cache the coordinate values for efficiency.
- *these are redundant information when
- *the grid is uniform.
- */
- Real* u_values; /*size is n_ulines*/
- Real* v_values; /*size is n_vlines*/
-
- Int is_uniform;
-
-public:
- //uniform grid constructor
- gridWrap(Int nUlines, Int nVlines,
- Real uMin, Real uMax,
- Real vMin, Real vMax
- );
-
- //nonuniform grid constructor.
- gridWrap(Int nUlines, Real *uvals,
- Int nVlines, Real *vvlas
- );
- ~gridWrap();
-
- void print();
- Int get_n_ulines() {return n_ulines;}
- Int get_n_vlines() {return n_vlines;}
- Real get_u_min() {return u_min;}
- Real get_u_max() {return u_max;}
- Real get_v_min() {return v_min;}
- Real get_v_max() {return v_max;}
-
- Real get_u_value(Int i)
- {
- assert(i<n_ulines);
- /*if(i>=n_ulines){printf("ERROR, n_ulines=%i,i=%i\n",n_ulines,i);exit(0);}*/
- return u_values[i];}
- Real get_v_value(Int j) {return v_values[j];}
-
- Real* get_u_values() {return u_values;}
- Real* get_v_values() {return v_values;}
-
- void outputFanWithPoint(Int v, Int uleft, Int uright,
- Real vert[2], primStream* pStream);
-
- void draw();
-
- Int isUniform() {return is_uniform;}
-};
-
-class gridBoundaryChain{
- gridWrap* grid;
- Int firstVlineIndex;
- Int nVlines;
- Int* ulineIndices; /*each v line has a boundary*/
- Int* innerIndices; /*the segment of the vertical gridline from */
- /*(innerIndices[i], i) to (innerIndices[i+1], i-1) */
- /*is inside the polygon: i=1,...,nVlines-1*/
-
- Real2* vertices; /*one grid point at each grid V-line, cached for efficiency*/
-
-public:
- gridBoundaryChain(gridWrap* gr, Int first_vline_index, Int n_vlines, Int* uline_indices, Int* inner_indices);
-
- ~gridBoundaryChain()
- {
- free(innerIndices);
- free(ulineIndices);
- free(vertices);
- }
-
- /*i indexes the vlines in this chain.
- */
- Int getVlineIndex(Int i) {return firstVlineIndex-i;}
- Int getUlineIndex(Int i) {return ulineIndices[i];}
- Real get_u_value(Int i) {return vertices[i][0];}
- Real get_v_value(Int i) {return vertices[i][1];}
- Int get_nVlines() {return nVlines;}
- Int getInnerIndex(Int i) {return innerIndices[i];}
- Real getInner_u_value(Int i) {return grid->get_u_value(innerIndices[i]);}
-
- Real* get_vertex(Int i) {return vertices[i];}
- gridWrap* getGrid() {return grid;}
- void leftEndFan(Int i, primStream* pStream);
- void rightEndFan(Int i, primStream* pStream);
-
- Int lookfor(Real v, Int i1, Int i2); //find i in [i1,i2] so that vertices[i][1]>= v > vertices[i+1][1]
- void draw();
- void drawInner();
-};
-
-#endif
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include "gluos.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <GL/gl.h>
-
-#include "glimports.h"
-#include "zlassert.h"
-
-#include "monoChain.h"
-#include "quicksort.h"
-#include "searchTree.h"
-#include "polyUtil.h"
-
-#ifndef max
-#define max(a,b) ((a>b)? a:b)
-#endif
-#ifndef min
-#define min(a,b) ((a>b)? b:a)
-#endif
-
-extern Int isCusp(directedLine *v);
-extern Int deleteRepeatDiagonals(Int num_diagonals, directedLine** diagonal_vertices, directedLine** new_vertices);
-
-//for debug purpose only
-#if 0 // UNUSED
-static void drawDiagonals(Int num_diagonals, directedLine** diagonal_vertices)
-{
- Int i;
- for(i=0; i<num_diagonals; i++)
- {
- glBegin(GL_LINE);
- glVertex2fv(diagonal_vertices[2*i]->head());
- glVertex2fv(diagonal_vertices[2*i+1]->head());
- glEnd();
- }
-}
-#endif
-
-/*given (x_1, y_1) and (x_2, y_2), and y
- *return x such that (x,y) is on the line
- */
-inline Real intersectHoriz(Real x1, Real y1, Real x2, Real y2, Real y)
-{
- return ((y2==y1)? (x1+x2)*0.5 : x1 + ((y-y1)/(y2-y1)) * (x2-x1));
-}
-
-//compare the heads of the two chains
-static int compChainHeadInY(monoChain* mc1, monoChain* mc2)
-{
- return compV2InY(mc1->getHead()->head(), mc2->getHead()->head());
-}
-
-monoChain::monoChain(directedLine* cHead, directedLine* cTail)
-{
- chainHead = cHead;
- chainTail = cTail;
- next = this;
- prev = this;
-
- nextPolygon = NULL;
-
- //compute bounding box
- directedLine* temp;
- minX = maxX = chainTail->head()[0];
- minY = maxY = chainTail->head()[1];
-
- for(temp=chainHead; temp!=cTail; temp = temp->getNext())
- {
- if(temp->head()[0] < minX)
- minX = temp->head()[0];
- if(temp->head()[0] > maxX)
- maxX = temp->head()[0];
-
- if(temp->head()[1] < minY)
- minY = temp->head()[1];
- if(temp->head()[1] > maxY)
- maxY = temp->head()[1];
- }
-
- //check whether the chain is increasing or decreasing
- if(chainHead->compInY(chainTail) <0)
- isIncrease = 1;
- else
- isIncrease = 0;
-
- //initilize currrent, this is used for accelerating search
- if(isIncrease)
- current = chainHead;
- else
- current = chainTail;
-
- isKey = 0;
- keyY = 0;
-}
-
-//insert a new line between prev and this
-void monoChain::insert(monoChain* nc)
-{
- nc->next = this;
- nc->prev = prev;
- prev->next = nc;
- prev = nc;
-}
-
-void monoChain::deleteLoop()
-{
- monoChain *temp, *tempNext;
- prev->next = NULL;
- for(temp=this; temp != NULL; temp = tempNext)
- {
- tempNext = temp->next;
- delete temp;
- }
-}
-
-void monoChain::deleteLoopList()
-{
- monoChain *temp, *tempNext;
- for(temp=this; temp != NULL; temp = tempNext)
- {
- tempNext = temp->nextPolygon;
- temp->deleteLoop();
- }
-}
-
-Int monoChain::toArraySingleLoop(monoChain** array, Int index)
-{
- monoChain *temp;
- array[index++] = this;
- for(temp = next; temp != this; temp = temp->next)
- {
- array[index++] = temp;
- }
- return index;
-}
-
-monoChain** monoChain::toArrayAllLoops(Int& num_chains)
-{
- num_chains = numChainsAllLoops();
- monoChain **ret = (monoChain**) malloc(sizeof(monoChain*) * num_chains);
- assert(ret);
- monoChain *temp;
- Int index = 0;
- for(temp = this; temp != NULL; temp=temp->nextPolygon){
- index = temp->toArraySingleLoop(ret, index);
- }
- return ret;
-}
-
-Int monoChain::numChainsSingleLoop()
-{
- Int ret=0;
- monoChain* temp;
- if(next == this) return 1;
- ret = 1;
- for(temp=next; temp != this; temp = temp->next)
- ret++;
- return ret;
-}
-
-Int monoChain::numChainsAllLoops()
-{
- Int ret=0;
- monoChain *temp;
- for(temp =this; temp != NULL; temp = temp->nextPolygon)
- ret += temp->numChainsSingleLoop();
- return ret;
-}
-
-//update 'current'
-Real monoChain::chainIntersectHoriz(Real y)
-{
- directedLine* temp;
- if(isIncrease)
- {
- for(temp= current; temp != chainTail; temp = temp->getNext())
- {
- if(temp->head()[1] > y)
- break;
- }
- current = temp->getPrev();
- }
- else
- {
- for(temp = current; temp != chainHead; temp = temp->getPrev())
- {
- if(temp->head()[1] > y)
- break;
- }
- current = temp->getNext();
- }
- return intersectHoriz(current->head()[0], current->head()[1], current->tail()[0], current->tail()[1], y);
-}
-
-monoChain* directedLineLoopToMonoChainLoop(directedLine* loop)
-{
- directedLine *temp;
- monoChain *ret=NULL;
-
- //find the first cusp
- directedLine *prevCusp=NULL;
- directedLine *firstCusp;
-
- if(isCusp(loop))
- prevCusp = loop;
- else
- {
- for(temp = loop->getNext(); temp != loop; temp = temp->getNext())
- if(isCusp(temp))
- break;
- prevCusp = temp;
- }
- firstCusp = prevCusp;
-//printf("first cusp is (%f,%f), (%f,%f), (%f,%f)\n", prevCusp->getPrev()->head()[0], prevCusp->getPrev()->head()[1], prevCusp->head()[0], prevCusp->head()[1], prevCusp->tail()[0], prevCusp->tail()[1]);
-
- for(temp = prevCusp->getNext(); temp != loop; temp = temp->getNext())
- {
- if(isCusp(temp))
- {
-//printf("the cusp is (%f,%f), (%f,%f), (%f,%f)\n", temp->getPrev()->head()[0], temp->getPrev()->head()[1], temp->head()[0], temp->head()[1], temp->tail()[0], temp->tail()[1]);
- if(ret == NULL)
- {
- ret = new monoChain(prevCusp, temp);
- }
- else
- ret->insert(new monoChain(prevCusp, temp));
- prevCusp = temp;
- }
- }
- assert(ret);
- ret->insert(new monoChain(prevCusp, firstCusp));
-
- return ret;
-}
-
-monoChain* directedLineLoopListToMonoChainLoopList(directedLine* list)
-{
- directedLine* temp;
- monoChain* mc;
- monoChain* mcEnd;
- mc = directedLineLoopToMonoChainLoop(list);
- mcEnd = mc;
- for(temp = list->getNextPolygon(); temp != NULL; temp = temp->getNextPolygon())
- {
- monoChain *newLoop = directedLineLoopToMonoChainLoop(temp);
- mcEnd->setNextPolygon(newLoop);
- mcEnd = newLoop;
- }
- return mc;
-}
-
-/*compare two edges of a polygon.
- *edge A < edge B if there is a horizontal line so that the intersection
- *with A is to the left of the intersection with B.
- *This function is used in sweepY for the dynamic search tree insertion to
- *order the edges.
- * Implementation: (x_1,y_1) and (x_2, y_2)
- */
-static Int compEdges(directedLine *e1, directedLine *e2)
-{
- Real* head1 = e1->head();
- Real* tail1 = e1->tail();
- Real* head2 = e2->head();
- Real* tail2 = e2->tail();
-/*
- Real h10 = head1[0];
- Real h11 = head1[1];
- Real t10 = tail1[0];
- Real t11 = tail1[1];
- Real h20 = head2[0];
- Real h21 = head2[1];
- Real t20 = tail2[0];
- Real t21 = tail2[1];
-*/
- Real e1_Ymax, e1_Ymin, e2_Ymax, e2_Ymin;
-/*
- if(h11>t11) {
- e1_Ymax= h11;
- e1_Ymin= t11;
- }
- else{
- e1_Ymax = t11;
- e1_Ymin = h11;
- }
-
- if(h21>t21) {
- e2_Ymax= h21;
- e2_Ymin= t21;
- }
- else{
- e2_Ymax = t21;
- e2_Ymin = h21;
- }
-*/
-
- if(head1[1]>tail1[1]) {
- e1_Ymax= head1[1];
- e1_Ymin= tail1[1];
- }
- else{
- e1_Ymax = tail1[1];
- e1_Ymin = head1[1];
- }
-
- if(head2[1]>tail2[1]) {
- e2_Ymax= head2[1];
- e2_Ymin= tail2[1];
- }
- else{
- e2_Ymax = tail2[1];
- e2_Ymin = head2[1];
- }
-
-
- /*Real e1_Ymax = max(head1[1], tail1[1]);*/ /*max(e1->head()[1], e1->tail()[1]);*/
- /*Real e1_Ymin = min(head1[1], tail1[1]);*/ /*min(e1->head()[1], e1->tail()[1]);*/
- /*Real e2_Ymax = max(head2[1], tail2[1]);*/ /*max(e2->head()[1], e2->tail()[1]);*/
- /*Real e2_Ymin = min(head2[1], tail2[1]);*/ /*min(e2->head()[1], e2->tail()[1]);*/
-
- Real Ymax = min(e1_Ymax, e2_Ymax);
- Real Ymin = max(e1_Ymin, e2_Ymin);
-
- Real y = 0.5*(Ymax + Ymin);
-
-/* Real x1 = intersectHoriz(e1->head()[0], e1->head()[1], e1->tail()[0], e1->tail()[1], y);
- Real x2 = intersectHoriz(e2->head()[0], e2->head()[1], e2->tail()[0], e2->tail()[1], y);
-*/
-/*
- Real x1 = intersectHoriz(h10, h11, t10, t11, y);
- Real x2 = intersectHoriz(h20, h21, t20, t21, y);
-*/
- Real x1 = intersectHoriz(head1[0], head1[1], tail1[0], tail1[1], y);
- Real x2 = intersectHoriz(head2[0], head2[1], tail2[0], tail2[1], y);
-
- if(x1<= x2) return -1;
- else return 1;
-}
-
-Int compChains(monoChain* mc1, monoChain* mc2)
-{
- Real y;
- assert(mc1->isKey || mc2->isKey);
- if(mc1->isKey)
- y = mc1->keyY;
- else
- y = mc2->keyY;
- directedLine *d1 = mc1->find(y);
- directedLine *d2 = mc2->find(y);
- mc2->find(y);
-// Real x1 = mc1->chainIntersectHoriz(y);
-// Real x2 = mc2->chainIntersectHoriz(y);
- return compEdges(d1, d2);
-}
-
-//this function modifies current for efficiency
-directedLine* monoChain::find(Real y)
-{
- directedLine *ret;
- directedLine *temp;
- assert(current->head()[1] <= y);
- if(isIncrease)
- {
- assert(chainTail->head()[1] >=y);
- for(temp=current; temp!=chainTail; temp = temp->getNext())
- {
- if(temp->head()[1] > y)
- break;
- }
- current = temp->getPrev();
- ret = current;
- }
- else
- {
- for(temp=current; temp != chainHead; temp = temp->getPrev())
- {
- if(temp->head()[1] > y)
- break;
- }
- current = temp->getNext();
- ret = temp;
- }
- return ret;
-}
-
-void monoChain::printOneChain()
-{
- directedLine* temp;
- for(temp = chainHead; temp != chainTail; temp = temp->getNext())
- {
- printf("(%f,%f) ", temp->head()[0], temp->head()[1]);
- }
- printf("(%f,%f) \n", chainTail->head()[0], chainTail->head()[1]);
-}
-
-void monoChain::printChainLoop()
-{
- monoChain* temp;
- this->printOneChain();
- for(temp = next; temp != this; temp = temp->next)
- {
- temp->printOneChain();
- }
- printf("\n");
-}
-
-void monoChain::printAllLoops()
-{
- monoChain* temp;
- for(temp=this; temp != NULL; temp = temp->nextPolygon)
- temp->printChainLoop();
-}
-
-//return 1 if error occures
-Int MC_sweepY(Int nVertices, monoChain** sortedVertices, sweepRange** ret_ranges)
-{
- Int i;
- Real keyY;
- Int errOccur=0;
-//printf("enter MC_sweepY\n");
-//printf("nVertices=%i\n", nVertices);
- /*for each vertex in the sorted list, update the binary search tree.
- *and store the range information for each vertex.
- */
- treeNode* searchTree = NULL;
-//printf("nVertices=%i\n", nVertices);
- for(i=0; i<nVertices; i++)
- {
- monoChain* vert = sortedVertices[i];
- keyY = vert->getHead()->head()[1]; //the sweep line
- directedLine *dline = vert->getHead();
- directedLine *dlinePrev = dline->getPrev();
- if(isBelow(dline, dline) && isBelow(dline, dlinePrev))
- {
-//printf("case 1\n");
- //this<v and prev < v
- //delete both edges
- vert->isKey = 1;
- vert->keyY = keyY;
- treeNode* thisNode = TreeNodeFind(searchTree, vert, (Int (*) (void *, void *))compChains);
- vert->isKey = 0;
-
- vert->getPrev()->isKey = 1;
- vert->getPrev()->keyY = keyY;
- treeNode* prevNode = TreeNodeFind(searchTree, vert->getPrev(), (Int (*) (void *, void *))compChains);
- vert->getPrev()->isKey = 0;
-
- if(cuspType(dline) == 1)//interior cusp
- {
-
- treeNode* leftEdge = TreeNodePredecessor(prevNode);
- treeNode* rightEdge = TreeNodeSuccessor(thisNode);
- if(leftEdge == NULL || rightEdge == NULL)
- {
- errOccur = 1;
- goto JUMP_HERE;
- }
-
- directedLine* leftEdgeDline = ((monoChain* ) leftEdge->key)->find(keyY);
-
-
-
- directedLine* rightEdgeDline = ((monoChain* ) rightEdge->key)->find(keyY);
-
- ret_ranges[i] = sweepRangeMake(leftEdgeDline, 1, rightEdgeDline, 1);
- }
- else /*exterior cusp*/
- {
- ret_ranges[i] = sweepRangeMake( dline, 1, dlinePrev, 1);
- }
-
- searchTree = TreeNodeDeleteSingleNode(searchTree, thisNode);
- searchTree = TreeNodeDeleteSingleNode(searchTree, prevNode);
-
- }
- else if(isAbove(dline, dline) && isAbove(dline, dlinePrev))
- {
-//printf("case 2\n");
- //insert both edges
- treeNode* thisNode = TreeNodeMake(vert);
- treeNode* prevNode = TreeNodeMake(vert->getPrev());
-
- vert->isKey = 1;
- vert->keyY = keyY;
- searchTree = TreeNodeInsert(searchTree, thisNode, (Int (*) (void *, void *))compChains);
- vert->isKey = 0;
-
- vert->getPrev()->isKey = 1;
- vert->getPrev()->keyY = keyY;
- searchTree = TreeNodeInsert(searchTree, prevNode, (Int (*) (void *, void *))compChains);
- vert->getPrev()->isKey = 0;
-
- if(cuspType(dline) == 1) //interior cusp
- {
-//printf("cuspType is 1\n");
- treeNode* leftEdge = TreeNodePredecessor(thisNode);
- treeNode* rightEdge = TreeNodeSuccessor(prevNode);
- if(leftEdge == NULL || rightEdge == NULL)
- {
- errOccur = 1;
- goto JUMP_HERE;
- }
-//printf("leftEdge is %i, rightEdge is %i\n", leftEdge, rightEdge);
- directedLine* leftEdgeDline = ((monoChain*) leftEdge->key)->find(keyY);
- directedLine* rightEdgeDline = ((monoChain*) rightEdge->key)->find(keyY);
- ret_ranges[i] = sweepRangeMake( leftEdgeDline, 1, rightEdgeDline, 1);
- }
- else //exterior cusp
- {
-//printf("cuspType is not 1\n");
- ret_ranges[i] = sweepRangeMake(dlinePrev, 1, dline, 1);
- }
- }
- else
- {
-//printf("%i,%i\n", isAbove(dline, dline), isAbove(dline, dlinePrev));
- errOccur = 1;
- goto JUMP_HERE;
-
- fprintf(stderr, "error in MC_sweepY\n");
- exit(1);
- }
- }
-
- JUMP_HERE:
- //finally clean up space: delete the search tree
- TreeNodeDeleteWholeTree(searchTree);
- return errOccur;
-}
-
-void MC_findDiagonals(Int total_num_edges, monoChain** sortedVertices,
- sweepRange** ranges, Int& num_diagonals,
- directedLine** diagonal_vertices)
-{
- Int i,j,k;
- k=0;
- //reset 'current' of all the monoChains
- for(i=0; i<total_num_edges; i++)
- sortedVertices[i]->resetCurrent();
-
- for(i=0; i<total_num_edges; i++)
- {
- directedLine* vert = sortedVertices[i]->getHead();
- directedLine* thisEdge = vert;
- directedLine* prevEdge = vert->getPrev();
- if(isBelow(vert, thisEdge) && isBelow(vert, prevEdge) && compEdges(prevEdge, thisEdge)<0)
- {
- //this is an upward interior cusp
- diagonal_vertices[k++] = vert;
-
- directedLine* leftEdge = ranges[i]->left;
- directedLine* rightEdge = ranges[i]->right;
-
- directedLine* leftVert = leftEdge;
- directedLine* rightVert = rightEdge->getNext();
- assert(leftVert->head()[1] >= vert->head()[1]);
- assert(rightVert->head()[1] >= vert->head()[1]);
- directedLine* minVert = (leftVert->head()[1] <= rightVert->head()[1])?leftVert:rightVert;
- Int found = 0;
- for(j=i+1; j<total_num_edges; j++)
- {
- if(sortedVertices[j]->getHead()->head()[1] > minVert->head()[1])
- break;
-
- if(sweepRangeEqual(ranges[i], ranges[j]))
- {
- found = 1;
- break;
- }
- }
-
- if(found)
- diagonal_vertices[k++] = sortedVertices[j]->getHead();
- else
- diagonal_vertices[k++] = minVert;
- }
- else if(isAbove(vert, thisEdge) && isAbove(vert, prevEdge) && compEdges(prevEdge, thisEdge)>0)
- {
- //downward interior cusp
- diagonal_vertices[k++] = vert;
- directedLine* leftEdge = ranges[i]->left;
- directedLine* rightEdge = ranges[i]->right;
- directedLine* leftVert = leftEdge->getNext();
- directedLine* rightVert = rightEdge;
- assert(leftVert->head()[1] <= vert->head()[1]);
- assert(rightVert->head()[1] <= vert->head()[1]);
- directedLine* maxVert = (leftVert->head()[1] > rightVert->head()[1])? leftVert:rightVert;
- Int found=0;
- for(j=i-1; j>=0; j--)
- {
- if(sortedVertices[j]->getHead()->head()[1] < maxVert->head()[1])
- break;
- if(sweepRangeEqual(ranges[i], ranges[j]))
- {
- found = 1;
- break;
- }
- }
- if(found)
- diagonal_vertices[k++] = sortedVertices[j]->getHead();
- else
- diagonal_vertices[k++] = maxVert;
- }
- }
- num_diagonals = k/2;
-}
-
-
-
-
-directedLine* MC_partitionY(directedLine *polygons, sampledLine **retSampledLines)
-{
-//printf("enter mc_partitionY\n");
- Int total_num_chains = 0;
- monoChain* loopList = directedLineLoopListToMonoChainLoopList(polygons);
- monoChain** array = loopList->toArrayAllLoops(total_num_chains);
-
- if(total_num_chains<=2) //there is just one single monotone polygon
- {
- loopList->deleteLoopList();
- free(array);
- *retSampledLines = NULL;
- return polygons;
- }
-
-//loopList->printAllLoops();
-//printf("total_num_chains=%i\n", total_num_chains);
- quicksort( (void**)array, 0, total_num_chains-1, (Int (*)(void*, void*))compChainHeadInY);
-//printf("after quicksort\n");
-
- sweepRange** ranges = (sweepRange**)malloc(sizeof(sweepRange*) * (total_num_chains));
- assert(ranges);
-
- if(MC_sweepY(total_num_chains, array, ranges))
- {
- loopList->deleteLoopList();
- free(array);
- *retSampledLines = NULL;
- return NULL;
- }
-//printf("after MC_sweepY\n");
-
-
- Int num_diagonals;
- /*number diagonals is < total_num_edges*total_num_edges*/
- directedLine** diagonal_vertices = (directedLine**) malloc(sizeof(directedLine*) * total_num_chains*2/*total_num_edges*/);
- assert(diagonal_vertices);
-
-//printf("before call MC_findDiagonales\n");
-
- MC_findDiagonals(total_num_chains, array, ranges, num_diagonals, diagonal_vertices);
-//printf("after call MC_findDia, num_diagnla=%i\n", num_diagonals);
-
- directedLine* ret_polygons = polygons;
- sampledLine* newSampledLines = NULL;
- Int i,k;
-
- num_diagonals=deleteRepeatDiagonals(num_diagonals, diagonal_vertices, diagonal_vertices);
-
-
-
-//drawDiagonals(num_diagonals, diagonal_vertices);
-//printf("diagoanls are \n");
-//for(i=0; i<num_diagonals; i++)
-// {
-// printf("(%f,%f)\n", diagonal_vertices[2*i]->head()[0], diagonal_vertices[2*i]->head()[1]);
-// printf("**(%f,%f)\n", diagonal_vertices[2*i+1]->head()[0], diagonal_vertices[2*i+1]->head()[1]);
-// }
-
- Int *removedDiagonals=(Int*)malloc(sizeof(Int) * num_diagonals);
- for(i=0; i<num_diagonals; i++)
- removedDiagonals[i] = 0;
-// printf("first pass\n");
-
-
- for(i=0,k=0; i<num_diagonals; i++,k+=2)
- {
-
-
- directedLine* v1=diagonal_vertices[k];
- directedLine* v2=diagonal_vertices[k+1];
- directedLine* ret_p1;
- directedLine* ret_p2;
-
- /*we ahve to determine whether v1 and v2 belong to the same polygon before
- *their structure are modified by connectDiagonal().
- */
-/*
- directedLine *root1 = v1->findRoot();
- directedLine *root2 = v2->findRoot();
- assert(root1);
- assert(root2);
-*/
-
-directedLine* root1 = v1->rootLinkFindRoot();
-directedLine* root2 = v2->rootLinkFindRoot();
-
- if(root1 != root2)
- {
-
- removedDiagonals[i] = 1;
- sampledLine* generatedLine;
-
-
-
- v1->connectDiagonal(v1,v2, &ret_p1, &ret_p2, &generatedLine, ret_polygons);
-
-
-
- newSampledLines = generatedLine->insert(newSampledLines);
-/*
- ret_polygons = ret_polygons->cutoffPolygon(root1);
-
- ret_polygons = ret_polygons->cutoffPolygon(root2);
- ret_polygons = ret_p1->insertPolygon(ret_polygons);
-root1->rootLinkSet(ret_p1);
-root2->rootLinkSet(ret_p1);
-ret_p1->rootLinkSet(NULL);
-ret_p2->rootLinkSet(ret_p1);
-*/
- ret_polygons = ret_polygons->cutoffPolygon(root2);
-
-
-
-root2->rootLinkSet(root1);
-ret_p1->rootLinkSet(root1);
-ret_p2->rootLinkSet(root1);
-
- /*now that we have connected the diagonal v1 and v2,
- *we have to check those unprocessed diagonals which
- *have v1 or v2 as an end point. Notice that the head of v1
- *has the same coodinates as the head of v2->prev, and the head of
- *v2 has the same coordinate as the head of v1->prev.
- *Suppose these is a diagonal (v1, x). If (v1,x) is still a valid
- *diagonal, then x should be on the left hand side of the directed line: *v1->prev->head -- v1->head -- v1->tail. Otherwise, (v1,x) should be
- *replaced by (v2->prev, x), that is, x is on the left of
- * v2->prev->prev->head, v2->prev->head, v2->prev->tail.
- */
- Int ii, kk;
- for(ii=0, kk=0; ii<num_diagonals; ii++, kk+=2)
- if( removedDiagonals[ii]==0)
- {
- directedLine* d1=diagonal_vertices[kk];
- directedLine* d2=diagonal_vertices[kk+1];
- /*check d1, and replace diagonal_vertices[kk] if necessary*/
- if(d1 == v1) {
- /*check if d2 is to left of v1->prev->head:v1->head:v1->tail*/
- if(! pointLeft2Lines(v1->getPrev()->head(),
- v1->head(), v1->tail(), d2->head()))
- {
-/*
- assert(pointLeft2Lines(v2->getPrev()->getPrev()->head(),
- v2->getPrev()->head(),
- v2->getPrev()->tail(), d2->head()));
-*/
- diagonal_vertices[kk] = v2->getPrev();
- }
- }
- if(d1 == v2) {
- /*check if d2 is to left of v2->prev->head:v2->head:v2->tail*/
- if(! pointLeft2Lines(v2->getPrev()->head(),
- v2->head(), v2->tail(), d2->head()))
- {
-/*
- assert(pointLeft2Lines(v1->getPrev()->getPrev()->head(),
- v1->getPrev()->head(),
- v1->getPrev()->tail(), d2->head()));
-*/
- diagonal_vertices[kk] = v1->getPrev();
- }
- }
- /*check d2 and replace diagonal_vertices[k+1] if necessary*/
- if(d2 == v1) {
- /*check if d1 is to left of v1->prev->head:v1->head:v1->tail*/
- if(! pointLeft2Lines(v1->getPrev()->head(),
- v1->head(), v1->tail(), d1->head()))
- {
-/* assert(pointLeft2Lines(v2->getPrev()->getPrev()->head(),
- v2->getPrev()->head(),
- v2->getPrev()->tail(), d1->head()));
-*/
- diagonal_vertices[kk+1] = v2->getPrev();
- }
- }
- if(d2 == v2) {
- /*check if d1 is to left of v2->prev->head:v2->head:v2->tail*/
- if(! pointLeft2Lines(v2->getPrev()->head(),
- v2->head(), v2->tail(), d1->head()))
- {
-/* assert(pointLeft2Lines(v1->getPrev()->getPrev()->head(),
- v1->getPrev()->head(),
- v1->getPrev()->tail(), d1->head()));
-*/
- diagonal_vertices[kk+1] = v1->getPrev();
- }
- }
- }
-}/*end if (root1 not equal to root 2)*/
-}
-
- /*second pass, now all diagoals should belong to the same polygon*/
-//printf("second pass: \n");
-
-// for(i=0; i<num_diagonals; i++)
-// printf("%i ", removedDiagonals[i]);
-
-
- for(i=0,k=0; i<num_diagonals; i++, k += 2)
- if(removedDiagonals[i] == 0)
- {
-
-
- directedLine* v1=diagonal_vertices[k];
- directedLine* v2=diagonal_vertices[k+1];
-
-
-
- directedLine* ret_p1;
- directedLine* ret_p2;
-
- /*we ahve to determine whether v1 and v2 belong to the same polygon before
- *their structure are modified by connectDiagonal().
- */
- directedLine *root1 = v1->findRoot();
-/*
- directedLine *root2 = v2->findRoot();
-
-
-
- assert(root1);
- assert(root2);
- assert(root1 == root2);
- */
- sampledLine* generatedLine;
-
-
-
- v1->connectDiagonal(v1,v2, &ret_p1, &ret_p2, &generatedLine, ret_polygons);
- newSampledLines = generatedLine->insert(newSampledLines);
-
- ret_polygons = ret_polygons->cutoffPolygon(root1);
-
- ret_polygons = ret_p1->insertPolygon(ret_polygons);
-
- ret_polygons = ret_p2->insertPolygon(ret_polygons);
-
-
-
- for(Int j=i+1; j<num_diagonals; j++)
- {
- if(removedDiagonals[j] ==0)
- {
-
- directedLine* temp1=diagonal_vertices[2*j];
- directedLine* temp2=diagonal_vertices[2*j+1];
- if(temp1==v1 || temp1==v2 || temp2==v1 || temp2==v2)
- if(! temp1->samePolygon(temp1, temp2))
- {
- /*if temp1 and temp2 are in different polygons,
- *then one of them must be v1 or v2.
- */
-
-
-
- assert(temp1==v1 || temp1 == v2 || temp2==v1 || temp2 ==v2);
- if(temp1==v1)
- {
- diagonal_vertices[2*j] = v2->getPrev();
- }
- if(temp2==v1)
- {
- diagonal_vertices[2*j+1] = v2->getPrev();
- }
- if(temp1==v2)
- {
- diagonal_vertices[2*j] = v1->getPrev();
- }
- if(temp2==v2)
- {
- diagonal_vertices[2*j+1] = v1->getPrev();
- }
- }
- }
- }
-
- }
-
-
- //clean up
- loopList->deleteLoopList();
- free(array);
- free(ranges);
- free(diagonal_vertices);
- free(removedDiagonals);
-
- *retSampledLines = newSampledLines;
- return ret_polygons;
-}
-
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-#ifndef _MONO_CHAIN_H
-#define _MONO_CHAIN_H
-
-#include "directedLine.h"
-#include "partitionY.h"
-
-class monoChain;
-
-class monoChain{
- directedLine* chainHead;
- directedLine* chainTail;
- monoChain* next;
- monoChain* prev;
- monoChain* nextPolygon; //a list of polygons
-
- //cached informatin
- //bounding box
- Real minX, maxX, minY, maxY;
- Int isIncrease;
-
- //for efficiently comparing two chains
-
- directedLine* current;
-
-public:
- monoChain(directedLine* cHead, directedLine* cTail);
- ~monoChain() {}
-
- inline void setNext(monoChain* n) {next = n;}
- inline void setPrev(monoChain* p) {prev = p;}
- inline void setNextPolygon(monoChain* np) {nextPolygon = np;}
- inline monoChain* getNext() {return next;}
- inline monoChain* getPrev() {return prev;}
- inline directedLine* getHead() {return chainHead;}
- inline directedLine* getTail() {return chainTail;}
-
- inline void resetCurrent() { current = ((isIncrease==1)? chainHead:chainTail);}
-
- void deleteLoop();
- void deleteLoopList();
-
- //insert a new chain between prev and this
- void insert(monoChain* nc);
-
- Int numChainsSingleLoop();
- Int numChainsAllLoops();
- monoChain** toArrayAllLoops(Int& num_chains);
- Int toArraySingleLoop(monoChain** array, Int index);
-
- Int isKey;
- Real keyY; //the current horizotal line
- Real chainIntersectHoriz(Real y); //updates current incrementally for efficiency
- directedLine* find(Real y);//find dline so that y intersects dline.
-
- void printOneChain();
- void printChainLoop();
- void printAllLoops();
-
-};
-
-monoChain* directedLineLoopToMonoChainLoop(directedLine* loop);
-monoChain* directedLineLoopListToMonoChainLoopList(directedLine* list);
-Int MC_sweepY(Int nVertices, monoChain** sortedVertices, sweepRange** ret_ranges);
-
-void MC_findDiagonals(Int total_num_edges, monoChain** sortedVertices,
- sweepRange** ranges, Int& num_diagonals,
- directedLine** diagonal_vertices);
-
-directedLine* MC_partitionY(directedLine *polygons, sampledLine **retSampledLines);
-
-#endif
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
- *monoPolyPart.C
- *
- *To partition a v-monotone polygon into some uv-monotone polygons.
- *The algorithm is different from the general monotone partition algorithm.
- *while the general monotone partition algorithm works for this special case,
- *but it is more expensive (O(nlogn)). The algorithm implemented here takes
- *advantage of the fact that the input is a v-monotone polygon and it is
- *conceptually simpler and computationally cheaper (a linear time algorithm).
- *The algorithm is described in Zicheng Liu's paper
- * "Quality-Oriented Linear Time Tessellation".
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "directedLine.h"
-#include "monoPolyPart.h"
-
-/*a vertex is u_maximal if both of its two neightbors are to the left of this
- *vertex
- */
-static Int is_u_maximal(directedLine* v)
-{
- if (compV2InX(v->getPrev()->head(), v->head()) == -1 &&
- compV2InX(v->getNext()->head(), v->head()) == -1)
- return 1;
- else
- return 0;
-}
-
-/*a vertex is u_minimal if both of its two neightbors are to the right of this
- *vertex
- */
-static Int is_u_minimal(directedLine* v)
-{
- if (compV2InX(v->getPrev()->head(), v->head()) == 1 &&
- compV2InX(v->getNext()->head(), v->head()) == 1)
- return 1;
- else
- return 0;
-}
-
-/*poly: a v-monotone polygon
- *return: a linked list of uv-monotone polygons.
- */
-directedLine* monoPolyPart(directedLine* polygon)
-{
- //handle special cases:
- if(polygon == NULL)
- return NULL;
- if(polygon->getPrev() == polygon)
- return polygon;
- if(polygon->getPrev() == polygon->getNext())
- return polygon;
- if(polygon->getPrev()->getPrev() == polygon->getNext())
- return polygon;
-
- //find the top and bottom vertexes
- directedLine *tempV, *topV, *botV;
- topV = botV = polygon;
- for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext())
- {
- if(compV2InY(topV->head(), tempV->head())<0) {
- topV = tempV;
- }
- if(compV2InY(botV->head(), tempV->head())>0) {
- botV = tempV;
- }
- }
-
- //initilization
- directedLine *A, *B, *C, *D, *G, *H;
- //find A:the first u_maximal vertex on the left chain
- //and C: the left most vertex between top and A
- A = NULL;
- C = topV;
- for(tempV=topV->getNext(); tempV != botV; tempV = tempV->getNext())
- {
- if(tempV->head()[0] < C->head()[0])
- C = tempV;
-
- if(is_u_maximal(tempV))
- {
- A = tempV;
- break;
- }
- }
- if(A == NULL)
- {
- A = botV;
- if(A->head()[0] < C->head()[0])
- C = A;
- }
-
- //find B: the first u_minimal vertex on the right chain
- //and D: the right most vertex between top and B
- B = NULL;
- D = topV;
- for(tempV=topV->getPrev(); tempV != botV; tempV = tempV->getPrev())
- {
- if(tempV->head()[0] > D->head()[0])
- D = tempV;
- if(is_u_minimal(tempV))
- {
- B = tempV;
- break;
- }
- }
- if(B == NULL)
- {
- B = botV;
- if(B->head()[0] > D->head()[0])
- D = B;
- }
-
- //error checking XXX
- if(C->head()[0] >= D->head()[0])
- return polygon;
-
- //find G on the left chain that is right above B
- for(tempV=topV; compV2InY(tempV->head(), B->head()) == 1; tempV=tempV->getNext());
- G = tempV->getPrev();
- //find H on the right chain that is right above A
- for(tempV=topV; compV2InY(tempV->head(), A->head()) == 1; tempV = tempV->getPrev());
- H = tempV->getNext();
-
- //Main Loop
- directedLine* ret = NULL;
- directedLine* currentPolygon = polygon;
- while(1)
- {
- //if both B and D are equal to botV, then this polygon is already
- //u-monotone
- if(A == botV && B == botV)
- {
- ret = currentPolygon->insertPolygon(ret);
- return ret;
- }
- else //not u-monotone
- {
- directedLine *ret_p1, *ret_p2;
- if(compV2InY(A->head(),B->head()) == 1) //A is above B
- {
- directedLine* E = NULL;
- for(tempV = C; tempV != D; tempV = tempV->getPrev())
- {
- if(tempV->head()[0] >= A->head()[0])
- {
- E = tempV;
- break;
- }
- }
-
- if(E == NULL)
- E = D;
- if(E->head()[0]> H->head()[0])
- E = H;
- //connect AE and output polygon ECA
- polygon->connectDiagonal_2slines(A, E,
- &ret_p1,
- &ret_p2,
- NULL);
- ret = ret_p2->insertPolygon(ret);
- currentPolygon = ret_p1;
-
- if(E == D)
- D = ret_p1;
- if(E == H)
- H = ret_p1;
- if(G->head()[1] >= A->head()[1])
- G = A;
- //update A to be the next u-maxiaml vertex on left chain
- //and C the leftmost vertex between the old A and the new A
- C = A;
- for(tempV = A->getNext(); tempV != botV; tempV = tempV->getNext())
- {
-
- if(tempV->head()[0] < C->head()[0])
- C = tempV;
- if(is_u_maximal(tempV))
- {
- A = tempV;
- break;
- }
- }
-
- if(tempV == botV)
- {
- A = botV;
- if(botV->head()[0] < C->head()[0])
- C = botV;
- }
- //update H
-
- if(A == botV)
- H = botV;
- else
- {
- for(tempV = H; compV2InY(tempV->head(), A->head()) == 1; tempV = tempV->getPrev());
- H = tempV->getNext();
- }
-
- }
- else //A is below B
- {
-
- directedLine* F = NULL;
- for(tempV = D; tempV != C; tempV = tempV->getNext())
- {
- if(tempV->head()[0] <= B->head()[0])
- {
- F = tempV;
- break;
- }
- }
- if(F == NULL)
- F = C;
- if(F->head()[0] < G->head()[0])
- F = G;
-
- //connect FB
- polygon->connectDiagonal_2slines(F, B,
- &ret_p1,
- &ret_p2,
- NULL);
- ret = ret_p2->insertPolygon(ret);
- currentPolygon = ret_p1;
- B = ret_p1;
- if(H ->head()[1] >= B->head()[1])
- H = ret_p1;
-
- //update B to be the next u-minimal vertex on right chain
- //and D the rightmost vertex between the old B and the new B
- D = B;
- for(tempV = B->getPrev(); tempV != botV; tempV = tempV->getPrev())
- {
- if(tempV->head()[0] > D->head()[0])
- D = tempV;
- if(is_u_minimal(tempV))
- {
- B = tempV;
- break;
- }
- }
- if(tempV == botV)
- {
- B = botV;
- if(botV->head()[0] > D->head()[0])
- D = botV;
- }
- //update G
- if(B == botV)
- G = botV;
- else
- {
- for(tempV = G; compV2InY(tempV->head(), B->head()) == 1; tempV = tempV->getNext());
- G = tempV->getPrev();
- }
- } //end of A is below B
- } //end not u-monotone
- } //end of main loop
-}
-
-
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
- *monoPolyPart.h
- */
-
-#ifndef _MONO_POLY_PART_H
-#define _MONO_POLY_PART_H
-
-class directedLine;
-
-directedLine* monoPolyPart(directedLine* polygon);
-
-#endif
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "gluos.h"
-#include "glimports.h"
-#include "zlassert.h"
-
-#include "monoTriangulation.h"
-#include "polyUtil.h" /*for area*/
-#include "partitionX.h"
-#include "monoPolyPart.h"
-
-
-
-extern directedLine* polygonConvert(directedLine* polygon);
-
-/*poly is NOT deleted
- */
-void monoTriangulationOpt(directedLine* poly, primStream* pStream)
-{
- Int n_cusps;
- Int n_edges = poly->numEdges();
- directedLine** cusps = (directedLine**) malloc(sizeof(directedLine*)*n_edges);
- assert(cusps);
- findInteriorCuspsX(poly, n_cusps, cusps);
- if(n_cusps ==0) //u monotine
- {
- monoTriangulationFun(poly, compV2InX, pStream);
- }
- else if(n_cusps == 1) // one interior cusp
- {
- directedLine* new_polygon = polygonConvert(cusps[0]);
- directedLine* other = findDiagonal_singleCuspX(new_polygon);
- //<other> should NOT be null unless there are self-intersecting
- //trim curves. In that case, we don't want to core dump, instead,
- //we triangulate anyway, and print out error message.
- if(other == NULL)
- {
- monoTriangulationFun(poly, compV2InX, pStream);
- }
- else
- {
- directedLine* ret_p1;
- directedLine* ret_p2;
-
- new_polygon->connectDiagonal_2slines(new_polygon, other,
- &ret_p1,
- &ret_p2,
- new_polygon);
-
- monoTriangulationFun(ret_p1, compV2InX, pStream);
- monoTriangulationFun(ret_p2, compV2InX, pStream);
-
- ret_p1->deleteSinglePolygonWithSline();
- ret_p2->deleteSinglePolygonWithSline();
- }
- }
- else
- {
- //we need a general partitionX funtion (supposed to be in partitionX.C,
- //not implemented yet. XXX
- monoTriangulationFun(poly, compV2InY, pStream);
- }
-
- free(cusps);
-}
-
-void monoTriangulationRecOpt(Real* topVertex, Real* botVertex,
- vertexArray* left_chain, Int left_current,
- vertexArray* right_chain, Int right_current,
- primStream* pStream)
-{
- Int i,j;
- Int n_left = left_chain->getNumElements();
- Int n_right = right_chain->getNumElements();
- if(left_current>= n_left-1 ||
- right_current>= n_right-1)
- {
- monoTriangulationRec(topVertex, botVertex, left_chain, left_current,
- right_chain, right_current, pStream);
- return;
- }
- //now both left and right have at least two vertices each.
- Real left_v = left_chain->getVertex(left_current)[1];
- Real right_v = right_chain->getVertex(right_current)[1];
-
- if(left_v <= right_v) //first left vertex is below right
- {
- //find the last vertex of right which is above or equal to left
- for(j=right_current; j<=n_right-1; j++)
- {
- if(right_chain->getVertex(j)[1] < left_v)
- break;
- }
- monoTriangulationRecGen(topVertex, left_chain->getVertex(left_current),
- left_chain, left_current, left_current,
- right_chain, right_current, j-1,
- pStream);
- monoTriangulationRecOpt(right_chain->getVertex(j-1),
- botVertex,
- left_chain, left_current,
- right_chain, j,
- pStream);
- }
- else //first right vertex is strictly below left
- {
- //find the last vertex of left which is strictly above right
- for(i=left_current; i<=n_left-1; i++)
- {
- if(left_chain->getVertex(i)[1] <= right_v)
- break;
- }
- monoTriangulationRecGen(topVertex, right_chain->getVertex(right_current),
- left_chain, left_current, i-1,
- right_chain, right_current, right_current,
- pStream);
- monoTriangulationRecOpt(left_chain->getVertex(i-1),
- botVertex,
- left_chain, i,
- right_chain, right_current,
- pStream);
- }
-}
-
-
-void monoTriangulationRecGenTBOpt(Real* topVertex, Real* botVertex,
- vertexArray* inc_chain, Int inc_current, Int inc_end,
- vertexArray* dec_chain, Int dec_current, Int dec_end,
- primStream* pStream)
-{
- pStream->triangle(topVertex, inc_chain->getVertex(inc_current), dec_chain->getVertex(dec_current));
-
-/*printf("**(%f,%f)\n", inc_chain->getArray()[0][0],inc_chain->getArray()[0][1]);*/
- triangulateXYMonoTB(inc_end-inc_current+1, inc_chain->getArray()+inc_current, dec_end-dec_current+1, dec_chain->getArray()+dec_current, pStream);
-
- pStream->triangle(botVertex, dec_chain->getVertex(dec_end), inc_chain->getVertex(inc_end));
-}
-
-
-/*n_left>=1
- *n_right>=1
- *the strip is going top to bottom. compared to the funtion
- * triangulateXYmono()
- */
-void triangulateXYMonoTB(Int n_left, Real** leftVerts,
- Int n_right, Real** rightVerts,
- primStream* pStream)
-{
-
-
- Int i,j,k,l;
- Real* topMostV;
-
- assert(n_left>=1 && n_right>=1);
- if(leftVerts[0][1] >= rightVerts[0][1])
- {
- i=1;
- j=0;
- topMostV = leftVerts[0];
- }
- else
- {
- i=0;
- j=1;
- topMostV = rightVerts[0];
- }
-
- while(1)
- {
- if(i >= n_left) /*case1: no more in left*/
- {
-
- if(j<n_right-1) /*at least two vertices in right*/
- {
- pStream->begin();
- pStream->insert(topMostV);
- for(k=n_right-1; k>=j; k--)
- pStream->insert(rightVerts[j]);
-
- pStream->end(PRIMITIVE_STREAM_FAN);
-
- }
-
- break;
- }
- else if(j>= n_right) /*case2: no more in right*/
- {
-
- if(i<n_left-1) /*at least two vertices in left*/
- {
- pStream->begin();
- pStream->insert(topMostV);
-
- for(k=i; k<n_left; k++)
- pStream->insert(leftVerts[k]);
-
- pStream->end(PRIMITIVE_STREAM_FAN);
- }
-
- break;
- }
- else /* case3: neither is empty, plus the topMostV, there is at least one triangle to output*/
- {
-
- if(leftVerts[i][1] >= rightVerts[j][1])
- {
- pStream->begin();
- pStream->insert(rightVerts[j]); /*the origin of this fan*/
-
- pStream->insert(topMostV);
-
- /*find the last k>=i such that
- *leftverts[k][1] >= rightverts[j][1]
- */
- k=i;
- while(k<n_left)
- {
- if(leftVerts[k][1] < rightVerts[j][1])
- break;
- k++;
- }
- k--;
- for(l=i; l<=k; l++)
- {
- pStream->insert(leftVerts[l]);
- }
-
- pStream->end(PRIMITIVE_STREAM_FAN);
- //update i for next loop
- i = k+1;
- topMostV = leftVerts[k];
-
- }
- else /*leftVerts[i][1] < rightVerts[j][1]*/
- {
- pStream->begin();
- pStream->insert(leftVerts[i]);/*the origion of this fan*/
-
- /*find the last k>=j such that
- *rightverts[k][1] > leftverts[i][1]*/
- k=j;
- while(k< n_right)
- {
- if(rightVerts[k][1] <= leftVerts[i][1])
- break;
- k++;
- }
- k--;
-
- for(l=k; l>= j; l--)
- pStream->insert(rightVerts[l]);
-
- pStream->insert(topMostV);
- pStream->end(PRIMITIVE_STREAM_FAN);
- j=k+1;
- topMostV = rightVerts[j-1];
- }
- }
- }
-}
-
-static int chainConvex(vertexArray* inc_chain, Int inc_current, Int inc_end)
-{
- Int i;
- //if there are no more than 2 vertices, return 1
- if(inc_current >= inc_end-1) return 1;
- for(i=inc_current; i<= inc_end-2; i++)
- {
- if(area(inc_chain->getVertex(i), inc_chain->getVertex(i+1), inc_chain->getVertex(i+2)) <0)
- return 0;
- }
- return 1;
-}
-
-static int chainConcave(vertexArray* dec_chain, Int dec_current, Int dec_end)
-{
- Int i;
- //if there are no more than 2 vertices, return 1
- if(dec_current >= dec_end -1) return 1;
- for(i=dec_current; i<=dec_end-2; i++)
- {
- if(area(dec_chain->getVertex(i), dec_chain->getVertex(i+1), dec_chain->getVertex(i+2)) >0)
- return 0;
- }
- return 1;
-}
-
-void monoTriangulationRecGenInU(Real* topVertex, Real* botVertex,
- vertexArray* inc_chain, Int inc_current, Int inc_end,
- vertexArray* dec_chain, Int dec_current, Int dec_end,
- primStream* pStream)
-{
-
-}
-
-void monoTriangulationRecGenOpt(Real* topVertex, Real* botVertex,
- vertexArray* inc_chain, Int inc_current, Int inc_end,
- vertexArray* dec_chain, Int dec_current, Int dec_end,
- primStream* pStream)
-{
- Int i;
- //copy this to a polygon: directedLine Lioop
- sampledLine* sline;
- directedLine* dline;
- directedLine* poly;
-
- if(inc_current <= inc_end) //at least one vertex in inc_chain
- {
- sline = new sampledLine(topVertex, inc_chain->getVertex(inc_current));
- poly = new directedLine(INCREASING, sline);
- for(i=inc_current; i<=inc_end-1; i++)
- {
- sline = new sampledLine(inc_chain->getVertex(i), inc_chain->getVertex(i+1));
- dline = new directedLine(INCREASING, sline);
- poly->insert(dline);
- }
- sline = new sampledLine(inc_chain->getVertex(inc_end), botVertex);
- dline = new directedLine(INCREASING, sline);
- poly->insert(dline);
- }
- else //inc_chian is empty
- {
- sline = new sampledLine(topVertex, botVertex);
- dline = new directedLine(INCREASING, sline);
- poly = dline;
- }
-
- assert(poly != NULL);
-
- if(dec_current <= dec_end) //at least on vertex in dec_Chain
- {
- sline = new sampledLine(botVertex, dec_chain->getVertex(dec_end));
- dline = new directedLine(INCREASING, sline);
- poly->insert(dline);
- for(i=dec_end; i>dec_current; i--)
- {
- sline = new sampledLine(dec_chain->getVertex(i), dec_chain->getVertex(i-1));
- dline = new directedLine(INCREASING, sline);
- poly->insert(dline);
- }
- sline = new sampledLine(dec_chain->getVertex(dec_current), topVertex);
- dline = new directedLine(INCREASING, sline);
- poly->insert(dline);
- }
- else //dec_chain is empty
- {
- sline = new sampledLine(botVertex, topVertex);
- dline = new directedLine(INCREASING, sline);
- poly->insert(dline);
- }
-
- {
- Int n_cusps;
- Int n_edges = poly->numEdges();
- directedLine** cusps = (directedLine**) malloc(sizeof(directedLine*)*n_edges);
- assert(cusps);
- findInteriorCuspsX(poly, n_cusps, cusps);
-
- if(n_cusps ==0) //u monotine
- {
- monoTriangulationFun(poly, compV2InX, pStream);
- }
- else if(n_cusps == 1) // one interior cusp
- {
- directedLine* new_polygon = polygonConvert(cusps[0]);
- directedLine* other = findDiagonal_singleCuspX(new_polygon);
- //<other> should NOT be null unless there are self-intersecting
- //trim curves. In that case, we don't want to core dump, instead,
- //we triangulate anyway, and print out error message.
- if(other == NULL)
- {
- monoTriangulationFun(poly, compV2InX, pStream);
- }
- else
- {
- directedLine* ret_p1;
- directedLine* ret_p2;
-
- new_polygon->connectDiagonal_2slines(new_polygon, other,
- &ret_p1,
- &ret_p2,
- new_polygon);
-
- monoTriangulationFun(ret_p1, compV2InX, pStream);
- monoTriangulationFun(ret_p2, compV2InX, pStream);
-
- ret_p1->deleteSinglePolygonWithSline();
- ret_p2->deleteSinglePolygonWithSline();
- }
- }
- else
- {
- //we need a general partitionX funtion (supposed to be in partitionX.C,
- //not implemented yet. XXX
- //monoTriangulationFun(poly, compV2InY, pStream);
-
- directedLine* new_polygon = polygonConvert(poly);
- directedLine* list = monoPolyPart(new_polygon);
- for(directedLine* temp = list; temp != NULL; temp = temp->getNextPolygon())
- {
- monoTriangulationFun(temp, compV2InX, pStream);
- }
- //clean up
- list->deletePolygonListWithSline();
-
- }
-
- free(cusps);
- /*
- if(numInteriorCuspsX(poly) == 0) //is u monotone
- monoTriangulationFun(poly, compV2InX, pStream);
- else //it is not u motone
- monoTriangulationFun(poly, compV2InY, pStream);
- */
- //clean up space
- poly->deleteSinglePolygonWithSline();
- return;
- }
-
- //apparently the following code is not reachable,
- //it is for test purpose
- if(inc_current > inc_end || dec_current>dec_end)
- {
- monoTriangulationRecGen(topVertex, botVertex, inc_chain, inc_current, inc_end,
- dec_chain, dec_current, dec_end,
- pStream);
- return;
- }
-
-
- if(
- area(dec_chain->getVertex(dec_current),
- topVertex,
- inc_chain->getVertex(inc_current)) >=0
- && chainConvex(inc_chain, inc_current, inc_end)
- && chainConcave(dec_chain, dec_current, dec_end)
- && area(inc_chain->getVertex(inc_end), botVertex, dec_chain->getVertex(dec_end)) >=0
- )
- {
- monoTriangulationRecFunGen(topVertex, botVertex,
- inc_chain, inc_current, inc_end,
- dec_chain, dec_current, dec_end,
- compV2InX, pStream);
- }
- else
- {
- monoTriangulationRecGen(topVertex, botVertex, inc_chain, inc_current, inc_end,
- dec_chain, dec_current, dec_end,
- pStream);
- }
-}
-
-/*if inc_current>inc_end, then inc_chain has no points to be considered
- *same for dec_chain
- */
-void monoTriangulationRecGen(Real* topVertex, Real* botVertex,
- vertexArray* inc_chain, Int inc_current, Int inc_end,
- vertexArray* dec_chain, Int dec_current, Int dec_end,
- primStream* pStream)
-{
- Real** inc_array ;
- Real** dec_array ;
- Int i;
-
- if(inc_current > inc_end && dec_current>dec_end)
- return;
- else if(inc_current>inc_end) /*no more vertices on inc_chain*/
- {
- dec_array = dec_chain->getArray();
- reflexChain rChain(100,0);
- /*put the top vertex into the reflex chain*/
- rChain.processNewVertex(topVertex, pStream);
- /*process all the vertices on the dec_chain*/
- for(i=dec_current; i<=dec_end; i++){
- rChain.processNewVertex(dec_array[i], pStream);
- }
- /*process the bottom vertex*/
- rChain.processNewVertex(botVertex, pStream);
- }
- else if(dec_current> dec_end) /*no more vertices on dec_chain*/
- {
- inc_array = inc_chain->getArray();
-
- reflexChain rChain(100,1);
- /*put the top vertex into the reflex chain*/
- rChain.processNewVertex(topVertex, pStream);
- /*process all the vertices on the inc_chain*/
- for(i=inc_current; i<=inc_end; i++){
- rChain.processNewVertex(inc_array[i], pStream);
- }
- /*process the bottom vertex*/
- rChain.processNewVertex(botVertex, pStream);
- }
- else /*neither chain is empty*/
- {
- inc_array = inc_chain -> getArray();
- dec_array = dec_chain -> getArray();
-
- /*if top of inc_chain is 'lower' than top of dec_chain, process all the
- *vertices on the dec_chain which are higher than top of inc_chain
- */
- if(compV2InY(inc_array[inc_current], dec_array[dec_current]) <= 0)
- {
-
- reflexChain rChain(100, 0);
- rChain.processNewVertex(topVertex, pStream);
- for(i=dec_current; i<=dec_end; i++)
- {
- if(compV2InY(inc_array[inc_current], dec_array[i]) <= 0)
- rChain.processNewVertex(dec_array[i], pStream);
- else
- break;
- }
- rChain.outputFan(inc_array[inc_current], pStream);
- monoTriangulationRecGen(dec_array[i-1], botVertex,
- inc_chain, inc_current, inc_end,
- dec_chain, i, dec_end,
- pStream);
- }
- else /*compV2InY(inc_array[inc_current], dec_array[dec_current]) > 0*/
- {
-
- reflexChain rChain(100, 1);
- rChain.processNewVertex(topVertex, pStream);
- for(i=inc_current; i<=inc_end; i++)
- {
- if(compV2InY(inc_array[i], dec_array[dec_current]) >0)
- rChain.processNewVertex(inc_array[i], pStream);
- else
- break;
- }
- rChain.outputFan(dec_array[dec_current], pStream);
- monoTriangulationRecGen(inc_array[i-1], botVertex,
- inc_chain, i, inc_end,
- dec_chain, dec_current,dec_end,
- pStream);
- }
- }/*end case neither is empty*/
-}
-
-void monoTriangulationFun(directedLine* monoPolygon, Int (*compFun)(Real*, Real*), primStream* pStream)
-{
- Int i;
- /*find the top vertex, bottom vertex, inccreasing chain, and decreasing chain,
- *then call monoTriangulationRec
- */
- directedLine* tempV;
- directedLine* topV;
- directedLine* botV;
- topV = botV = monoPolygon;
- for(tempV = monoPolygon->getNext(); tempV != monoPolygon; tempV = tempV->getNext())
- {
- if(compFun(topV->head(), tempV->head())<0) {
- topV = tempV;
- }
- if(compFun(botV->head(), tempV->head())>0) {
- botV = tempV;
- }
- }
-
- /*creat increase and decrease chains*/
- vertexArray inc_chain(20); /*this is a dynamic array*/
- for(i=1; i<=topV->get_npoints()-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/
- inc_chain.appendVertex(topV->getVertex(i));
- }
- for(tempV = topV->getNext(); tempV != botV; tempV = tempV->getNext())
- {
- for(i=0; i<=tempV->get_npoints()-2; i++){
- inc_chain.appendVertex(tempV->getVertex(i));
- }
- }
-
- vertexArray dec_chain(20);
- for(tempV = topV->getPrev(); tempV != botV; tempV = tempV->getPrev())
- {
- for(i=tempV->get_npoints()-2; i>=0; i--){
- dec_chain.appendVertex(tempV->getVertex(i));
- }
- }
- for(i=botV->get_npoints()-2; i>=1; i--){
- dec_chain.appendVertex(tempV->getVertex(i));
- }
-
- if (!(0 == inc_chain.getNumElements() && 0 == dec_chain.getNumElements())) {
- monoTriangulationRecFun(topV->head(), botV->head(), &inc_chain, 0,
- &dec_chain, 0, compFun, pStream);
- }
-}
-
-void monoTriangulation(directedLine* monoPolygon, primStream* pStream)
-{
- Int i;
- /*find the top vertex, bottom vertex, inccreasing chain, and decreasing chain,
- *then call monoTriangulationRec
- */
- directedLine* tempV;
- directedLine* topV;
- directedLine* botV;
- topV = botV = monoPolygon;
- for(tempV = monoPolygon->getNext(); tempV != monoPolygon; tempV = tempV->getNext())
- {
- if(compV2InY(topV->head(), tempV->head())<0) {
- topV = tempV;
- }
- if(compV2InY(botV->head(), tempV->head())>0) {
- botV = tempV;
- }
- }
- /*creat increase and decrease chains*/
- vertexArray inc_chain(20); /*this is a dynamic array*/
- for(i=1; i<=topV->get_npoints()-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/
- inc_chain.appendVertex(topV->getVertex(i));
- }
- for(tempV = topV->getNext(); tempV != botV; tempV = tempV->getNext())
- {
- for(i=0; i<=tempV->get_npoints()-2; i++){
- inc_chain.appendVertex(tempV->getVertex(i));
- }
- }
-
- vertexArray dec_chain(20);
- for(tempV = topV->getPrev(); tempV != botV; tempV = tempV->getPrev())
- {
- for(i=tempV->get_npoints()-2; i>=0; i--){
- dec_chain.appendVertex(tempV->getVertex(i));
- }
- }
- for(i=botV->get_npoints()-2; i>=1; i--){
- dec_chain.appendVertex(tempV->getVertex(i));
- }
-
- monoTriangulationRec(topV->head(), botV->head(), &inc_chain, 0, &dec_chain, 0, pStream);
-
-}
-
-/*the chain could be increasing or decreasing, although we use the
- * name inc_chain.
- *the argument is_increase_chain indicates whether this chain
- *is increasing (left chain in V-monotone case) or decreaing (right chain
- *in V-monotone case).
- */
-void monoTriangulation2(Real* topVertex, Real* botVertex,
- vertexArray* inc_chain, Int inc_smallIndex,
- Int inc_largeIndex,
- Int is_increase_chain,
- primStream* pStream)
-{
- assert( inc_chain != NULL);
- Real** inc_array ;
-
- if(inc_smallIndex > inc_largeIndex)
- return; //no triangles
- if(inc_smallIndex == inc_largeIndex)
- {
- if(is_increase_chain)
- pStream->triangle(inc_chain->getVertex(inc_smallIndex), botVertex, topVertex);
- else
- pStream->triangle(inc_chain->getVertex(inc_smallIndex), topVertex, botVertex);
- return;
- }
- Int i;
-
- if(is_increase_chain && botVertex[1] == inc_chain->getVertex(inc_largeIndex)[1])
- {
- pStream->triangle(botVertex, inc_chain->getVertex(inc_largeIndex-1),
- inc_chain->getVertex(inc_largeIndex));
- monoTriangulation2(topVertex, botVertex, inc_chain, inc_smallIndex,
- inc_largeIndex-1,
- is_increase_chain,
- pStream);
- return;
- }
- else if( (!is_increase_chain) && topVertex[1] == inc_chain->getVertex(inc_smallIndex)[1])
- {
- pStream->triangle(topVertex, inc_chain->getVertex(inc_smallIndex+1),
- inc_chain->getVertex(inc_smallIndex));
- monoTriangulation2(topVertex, botVertex, inc_chain, inc_smallIndex+1,
- inc_largeIndex, is_increase_chain, pStream);
- return ;
- }
-
- inc_array = inc_chain->getArray();
-
- reflexChain rChain(20,is_increase_chain); /*1 means the chain is increasing*/
-
- rChain.processNewVertex(topVertex, pStream);
-
- for(i=inc_smallIndex; i<=inc_largeIndex; i++){
- rChain.processNewVertex(inc_array[i], pStream);
- }
- rChain.processNewVertex(botVertex, pStream);
-
-}
-
-/*if compFun == compV2InY, top to bottom: V-monotone
- *if compFun == compV2InX, right to left: U-monotone
- */
-void monoTriangulationRecFunGen(Real* topVertex, Real* botVertex,
- vertexArray* inc_chain, Int inc_current, Int inc_end,
- vertexArray* dec_chain, Int dec_current, Int dec_end,
- Int (*compFun)(Real*, Real*),
- primStream* pStream)
-{
- assert( inc_chain != NULL && dec_chain != NULL);
- assert( ! (inc_current> inc_end &&
- dec_current> dec_end));
- /*
- Int inc_nVertices;
- Int dec_nVertices;
- */
- Real** inc_array ;
- Real** dec_array ;
- Int i;
- assert( ! ( (inc_chain==NULL) && (dec_chain==NULL)));
-
- if(inc_current> inc_end) /*no more vertices on inc_chain*/
- {
-
- dec_array = dec_chain->getArray();
- reflexChain rChain(20,0);
- /*put the top vertex into the reflex chain*/
- rChain.processNewVertex(topVertex, pStream);
- /*process all the vertices on the dec_chain*/
- for(i=dec_current; i<=dec_end; i++){
- rChain.processNewVertex(dec_array[i], pStream);
- }
- /*process the bottom vertex*/
- rChain.processNewVertex(botVertex, pStream);
-
- }
- else if(dec_current> dec_end) /*no more vertices on dec_chain*/
- {
- inc_array = inc_chain->getArray();
- reflexChain rChain(20,1);
- /*put the top vertex into the reflex chain*/
- rChain.processNewVertex(topVertex, pStream);
- /*process all the vertices on the inc_chain*/
- for(i=inc_current; i<=inc_end; i++){
- rChain.processNewVertex(inc_array[i], pStream);
- }
- /*process the bottom vertex*/
- rChain.processNewVertex(botVertex, pStream);
- }
- else /*neither chain is empty*/
- {
- inc_array = inc_chain -> getArray();
- dec_array = dec_chain -> getArray();
-
- /*if top of inc_chain is 'lower' than top of dec_chain, process all the
- *vertices on the dec_chain which are higher than top of inc_chain
- */
- if(compFun(inc_array[inc_current], dec_array[dec_current]) <= 0)
- {
-
- reflexChain rChain(20, 0);
- rChain.processNewVertex(topVertex, pStream);
- for(i=dec_current; i<=dec_end; i++)
- {
- if(compFun(inc_array[inc_current], dec_array[i]) <= 0)
- rChain.processNewVertex(dec_array[i], pStream);
- else
- break;
- }
- rChain.outputFan(inc_array[inc_current], pStream);
- monoTriangulationRecFunGen(dec_array[i-1], botVertex,
- inc_chain, inc_current, inc_end,
- dec_chain, i, dec_end,
- compFun,
- pStream);
- }
- else /*compFun(inc_array[inc_current], dec_array[dec_current]) > 0*/
- {
-
- reflexChain rChain(20, 1);
- rChain.processNewVertex(topVertex, pStream);
- for(i=inc_current; i<=inc_end; i++)
- {
- if(compFun(inc_array[i], dec_array[dec_current]) >0)
- rChain.processNewVertex(inc_array[i], pStream);
- else
- break;
- }
- rChain.outputFan(dec_array[dec_current], pStream);
- monoTriangulationRecFunGen(inc_array[i-1], botVertex,
- inc_chain, i,inc_end,
- dec_chain, dec_current,dec_end,
- compFun,
- pStream);
- }
- }/*end case neither is empty*/
-}
-
-/*if compFun == compV2InY, top to bottom: V-monotone
- *if compFun == compV2InX, right to left: U-monotone
- */
-void monoTriangulationRecFun(Real* topVertex, Real* botVertex,
- vertexArray* inc_chain, Int inc_current,
- vertexArray* dec_chain, Int dec_current,
- Int (*compFun)(Real*, Real*),
- primStream* pStream)
-{
- assert( inc_chain != NULL && dec_chain != NULL);
- assert( ! (inc_current>=inc_chain->getNumElements() &&
- dec_current>=dec_chain->getNumElements()));
- Int inc_nVertices;
- Int dec_nVertices;
- Real** inc_array ;
- Real** dec_array ;
- Int i;
- assert( ! ( (inc_chain==NULL) && (dec_chain==NULL)));
-
- if(inc_current>=inc_chain->getNumElements()) /*no more vertices on inc_chain*/
- {
-
- dec_array = dec_chain->getArray();
- dec_nVertices = dec_chain->getNumElements();
- reflexChain rChain(20,0);
- /*put the top vertex into the reflex chain*/
- rChain.processNewVertex(topVertex, pStream);
- /*process all the vertices on the dec_chain*/
- for(i=dec_current; i<dec_nVertices; i++){
- rChain.processNewVertex(dec_array[i], pStream);
- }
- /*process the bottom vertex*/
- rChain.processNewVertex(botVertex, pStream);
-
- }
- else if(dec_current>= dec_chain->getNumElements()) /*no more vertices on dec_chain*/
- {
- inc_array = inc_chain->getArray();
- inc_nVertices= inc_chain->getNumElements();
- reflexChain rChain(20,1);
- /*put the top vertex into the reflex chain*/
- rChain.processNewVertex(topVertex, pStream);
- /*process all the vertices on the inc_chain*/
- for(i=inc_current; i<inc_nVertices; i++){
- rChain.processNewVertex(inc_array[i], pStream);
- }
- /*process the bottom vertex*/
- rChain.processNewVertex(botVertex, pStream);
- }
- else /*neither chain is empty*/
- {
- inc_array = inc_chain -> getArray();
- dec_array = dec_chain -> getArray();
- inc_nVertices= inc_chain->getNumElements();
- dec_nVertices= dec_chain->getNumElements();
- /*if top of inc_chain is 'lower' than top of dec_chain, process all the
- *vertices on the dec_chain which are higher than top of inc_chain
- */
- if(compFun(inc_array[inc_current], dec_array[dec_current]) <= 0)
- {
-
- reflexChain rChain(20, 0);
- rChain.processNewVertex(topVertex, pStream);
- for(i=dec_current; i<dec_nVertices; i++)
- {
- if(compFun(inc_array[inc_current], dec_array[i]) <= 0)
- rChain.processNewVertex(dec_array[i], pStream);
- else
- break;
- }
- rChain.outputFan(inc_array[inc_current], pStream);
- monoTriangulationRecFun(dec_array[i-1], botVertex,
- inc_chain, inc_current,
- dec_chain, i,
- compFun,
- pStream);
- }
- else /*compFun(inc_array[inc_current], dec_array[dec_current]) > 0*/
- {
-
- reflexChain rChain(20, 1);
- rChain.processNewVertex(topVertex, pStream);
- for(i=inc_current; i<inc_nVertices; i++)
- {
- if(compFun(inc_array[i], dec_array[dec_current]) >0)
- rChain.processNewVertex(inc_array[i], pStream);
- else
- break;
- }
- rChain.outputFan(dec_array[dec_current], pStream);
- monoTriangulationRecFun(inc_array[i-1], botVertex,
- inc_chain, i,
- dec_chain, dec_current,
- compFun,
- pStream);
- }
- }/*end case neither is empty*/
-}
-
-
-void monoTriangulationRec(Real* topVertex, Real* botVertex,
- vertexArray* inc_chain, Int inc_current,
- vertexArray* dec_chain, Int dec_current,
- primStream* pStream)
-{
- assert( inc_chain != NULL && dec_chain != NULL);
- assert( ! (inc_current>=inc_chain->getNumElements() &&
- dec_current>=dec_chain->getNumElements()));
- Int inc_nVertices;
- Int dec_nVertices;
- Real** inc_array ;
- Real** dec_array ;
- Int i;
- assert( ! ( (inc_chain==NULL) && (dec_chain==NULL)));
-
- if(inc_current>=inc_chain->getNumElements()) /*no more vertices on inc_chain*/
- {
-
- dec_array = dec_chain->getArray();
- dec_nVertices = dec_chain->getNumElements();
- reflexChain rChain(20,0);
- /*put the top vertex into the reflex chain*/
- rChain.processNewVertex(topVertex, pStream);
- /*process all the vertices on the dec_chain*/
- for(i=dec_current; i<dec_nVertices; i++){
- rChain.processNewVertex(dec_array[i], pStream);
- }
- /*process the bottom vertex*/
- rChain.processNewVertex(botVertex, pStream);
-
- }
- else if(dec_current>= dec_chain->getNumElements()) /*no more vertices on dec_chain*/
- {
- inc_array = inc_chain->getArray();
- inc_nVertices= inc_chain->getNumElements();
- reflexChain rChain(20,1);
- /*put the top vertex into the reflex chain*/
- rChain.processNewVertex(topVertex, pStream);
- /*process all the vertices on the inc_chain*/
- for(i=inc_current; i<inc_nVertices; i++){
- rChain.processNewVertex(inc_array[i], pStream);
- }
- /*process the bottom vertex*/
- rChain.processNewVertex(botVertex, pStream);
- }
- else /*neither chain is empty*/
- {
- inc_array = inc_chain -> getArray();
- dec_array = dec_chain -> getArray();
- inc_nVertices= inc_chain->getNumElements();
- dec_nVertices= dec_chain->getNumElements();
- /*if top of inc_chain is 'lower' than top of dec_chain, process all the
- *vertices on the dec_chain which are higher than top of inc_chain
- */
- if(compV2InY(inc_array[inc_current], dec_array[dec_current]) <= 0)
- {
-
- reflexChain rChain(20, 0);
- rChain.processNewVertex(topVertex, pStream);
- for(i=dec_current; i<dec_nVertices; i++)
- {
- if(compV2InY(inc_array[inc_current], dec_array[i]) <= 0)
- rChain.processNewVertex(dec_array[i], pStream);
- else
- break;
- }
- rChain.outputFan(inc_array[inc_current], pStream);
- monoTriangulationRec(dec_array[i-1], botVertex,
- inc_chain, inc_current,
- dec_chain, i,
- pStream);
- }
- else /*compV2InY(inc_array[inc_current], dec_array[dec_current]) > 0*/
- {
-
- reflexChain rChain(20, 1);
- rChain.processNewVertex(topVertex, pStream);
- for(i=inc_current; i<inc_nVertices; i++)
- {
- if(compV2InY(inc_array[i], dec_array[dec_current]) >0)
- rChain.processNewVertex(inc_array[i], pStream);
- else
- break;
- }
- rChain.outputFan(dec_array[dec_current], pStream);
- monoTriangulationRec(inc_array[i-1], botVertex,
- inc_chain, i,
- dec_chain, dec_current,
- pStream);
- }
- }/*end case neither is empty*/
-}
-
-
-
-/* the name here assumes that the polygon is Y-monotone, but
- *this function also works for X-monotone polygons.
- * a monotne polygon consists of two extrem verteices: topVertex and botVertex, and
- *two monotone chains: inc_chain, and dec_chain. The edges of the increasing chain (inc_chain)
- *is ordered by following pointer: next, while the edges of the decreasing chain (dec_chain)
- *is ordered by following pointer: prev
- * inc_index index the vertex which is the toppest of the inc_chain which we are handling currently.
- * dec_index index the vertex which is the toppest of the dec_chain which we are handling currently.
- */
-void monoTriangulationRec(directedLine* inc_chain, Int inc_index,
- directedLine* dec_chain, Int dec_index,
- directedLine* topVertex, Int top_index,
- directedLine* botVertex,
- primStream* pStream)
-{
- Int i;
- directedLine *temp, *oldtemp = NULL;
- Int tempIndex, oldtempIndex = 0;
-
- assert(inc_chain != NULL && dec_chain != NULL);
-
- if(inc_chain == botVertex) {
- reflexChain rChain(20, 0);
- rChain.processNewVertex(topVertex->getVertex(top_index), pStream);
- for(i=dec_index; i< dec_chain->get_npoints(); i++){
- rChain.processNewVertex(dec_chain->getVertex(i), pStream);
- }
- for(temp = dec_chain->getPrev(); temp != botVertex; temp = temp->getPrev())
- {
- for(i=0; i<temp->get_npoints(); i++){
- rChain.processNewVertex(temp->getVertex(i), pStream);
- }
- }
- }
- else if(dec_chain==botVertex) {
- reflexChain rChain(20, 1);
- rChain.processNewVertex(topVertex->getVertex(top_index), pStream);
- for(i=inc_index; i< inc_chain->get_npoints(); i++){
- rChain.processNewVertex(inc_chain->getVertex(i), pStream);
- }
- for(temp = inc_chain->getPrev(); temp != botVertex; temp = temp->getNext())
- {
- for(i=0; i<temp->get_npoints(); i++){
- rChain.processNewVertex(temp->getVertex(i), pStream);
- }
- }
- }
- else /*neither reached the bottom*/{
- if(compV2InY(inc_chain->getVertex(inc_index), dec_chain->getVertex(dec_index)) <=0) {
- reflexChain rChain(20, 0);
- rChain.processNewVertex(topVertex -> getVertex(top_index), pStream);
- temp = dec_chain;
- tempIndex = dec_index;
- while( compV2InY(inc_chain->getVertex(inc_index), temp->getVertex(tempIndex))<=0) {
- oldtemp = temp;
- oldtempIndex = tempIndex;
- rChain.processNewVertex(temp->getVertex(tempIndex), pStream);
-
- if(tempIndex == temp->get_npoints()-1){
- tempIndex = 0;
- temp = temp->getPrev();
- }
- else{
- tempIndex++;
- }
- }
- rChain.outputFan(inc_chain->getVertex(inc_index), pStream);
- monoTriangulationRec(inc_chain, inc_index, temp, tempIndex, oldtemp, oldtempIndex, botVertex, pStream);
- }
- else /* >0*/ {
- reflexChain rChain(20, 1);
- rChain.processNewVertex(topVertex -> getVertex(top_index), pStream);
- temp = inc_chain;
- tempIndex = inc_index;
- while( compV2InY(temp->getVertex(tempIndex), dec_chain->getVertex(dec_index))>0){
- oldtemp = temp;
- oldtempIndex = tempIndex;
- rChain.processNewVertex(temp->getVertex(tempIndex), pStream);
-
- if(tempIndex == temp->get_npoints()-1){
- tempIndex = 0;
- temp = temp->getNext();
- }
- else{
- tempIndex++;
- }
- }
- rChain.outputFan(dec_chain->getVertex(dec_index), pStream);
- monoTriangulationRec(temp, tempIndex, dec_chain, dec_index, oldtemp, oldtempIndex, botVertex, pStream);
- }
- } /*end case neither reached the bottom*/
-}
-
-/***************************vertexArray begin here**********************************/
-vertexArray::vertexArray(Real2* vertices, Int nVertices)
-{
- Int i;
- size = index = nVertices;
- array = (Real**) malloc(sizeof(Real*) * nVertices);
- assert(array);
- for(i=0; i<nVertices; i++)
- {
- array[i] = vertices[i];
- array[i] = vertices[i];
- }
-}
-
-vertexArray::vertexArray(Int s)
-{
- size = s;
- array = (Real**) malloc(sizeof(Real*) * s);
- assert(array);
- index = 0;
-}
-
-vertexArray::~vertexArray()
-{
- free(array);
-}
-
-void vertexArray::appendVertex(Real* ptr)
-{
- Int i;
- if(index >= size){
- Real** temp = (Real**) malloc(sizeof(Real*) * (2*size +1));
- assert(temp);
- for(i=0; i<index; i++)
- temp[i] = array[i];
- free(array);
- array = temp;
- size = 2*size+1;
- }
- array[index++] = ptr;
-}
-
-void vertexArray::print()
-{
- printf("vertex Array:index=%i, size=%i\n", index, size);
- for(Int i=0; i<index; i++)
- {
- printf("(%f,%f) ", array[i][0], array[i][1]);
- }
- printf("\n");
-}
-
-/*find the first i such that array[i][1] >= v
- * and array[i+1][1] <v
- * if index == 0 (the array is empty, return -1.
- * if v is above all, return -1.
- * if v is below all, return index-1.
- */
-Int vertexArray::findIndexAbove(Real v)
-{
- Int i;
- if(index == 0)
- return -1;
- else if(array[0][1] < v)
- return -1;
- else
- {
- for(i=1; i<index; i++)
- {
- if(array[i][1] < v)
- break;
- }
- return i-1;
- }
-}
-
-/*find the first i<=endIndex such that array[i][1] <= v
- * and array[i-1][1] > v
- *if sartIndex>endIndex, then return endIndex+1.
- *otherwise, startIndex<=endIndex, it is assumed that
- * 0<=startIndex<=endIndex<index.
- * if v is below all, return endIndex+1
- * if v is above all, return startIndex.
- */
-Int vertexArray::findIndexBelowGen(Real v, Int startIndex, Int endIndex)
-{
- Int i;
- if(startIndex > endIndex)
- return endIndex+1;
- else if(array[endIndex][1] > v)
- return endIndex+1;
- else //now array[endIndex][1] <= v
- {
- for(i=endIndex-1; i>=startIndex; i--)
- {
- if(array[i][1] > v)
- break;
- }
- return i+1;
- }
-}
-
-/*find the first i<=endIndex such that array[i-1][1] >= v
- * and array[i][1] < v
- *if sartIndex>endIndex, then return endIndex+1.
- *otherwise, startIndex<=endIndex, it is assumed that
- * 0<=startIndex<=endIndex<index.
- * if v is below or equal to all, return endIndex+1
- * if v is strictly above all, return startIndex.
- */
-Int vertexArray::findIndexStrictBelowGen(Real v, Int startIndex, Int endIndex)
-{
- Int i;
- if(startIndex > endIndex)
- return endIndex+1;
- else if(array[endIndex][1] >= v)
- return endIndex+1;
- else //now array[endIndex][1] < v
- {
- for(i=endIndex-1; i>=startIndex; i--)
- {
- if(array[i][1] >= v)
- break;
- }
- return i+1;
- }
-}
-
-/*find the first i>startIndex such that array[i-1][1] > v
- * and array[i][1] >=v
- *if sartIndex>endIndex, then return startIndex-1.
- *otherwise, startIndex<=endIndex, it is assumed that
- * 0<=startIndex<=endIndex<index.
- * if v is strictly above all, return startIndex-1
- * if v is strictly below all, return endIndex.
- */
-Int vertexArray::findIndexFirstAboveEqualGen(Real v, Int startIndex, Int endIndex)
-{
-
- Int i;
- if(startIndex > endIndex)
- return startIndex-1;
- else if(array[startIndex][1] < v)
- return startIndex-1;
- else //now array[startIndex][1] >= v
- {
-
- for(i=startIndex; i<=endIndex; i++)
- {
- if(array[i][1] <= v)
- break;
- }
- if(i>endIndex) // v is strictly below all
- return endIndex;
- else if(array[i][1] == v)
- return i;
- else
- return i-1;
- }
-
-}
-
-
-/*find the first i>=startIndex such that array[i][1] >= v
- * and array[i+1][1] <v
- *if sartIndex>endIndex, then return startIndex-1.
- *otherwise, startIndex<=endIndex, it is assumed that
- * 0<=startIndex<=endIndex<index.
- * if v is above all, return startIndex-1
- * if v is below all, return endIndex.
- */
-Int vertexArray::findIndexAboveGen(Real v, Int startIndex, Int endIndex)
-{
- Int i;
- if(startIndex > endIndex)
- return startIndex-1;
- else if(array[startIndex][1] < v)
- return startIndex-1;
- else //now array[startIndex][1] >= v
- {
- for(i=startIndex+1; i<=endIndex; i++)
- {
- if(array[i][1] < v)
- break;
- }
- return i-1;
- }
-}
-
-Int vertexArray::findDecreaseChainFromEnd(Int begin, Int end)
-{
- Int i = end;
- Real prevU = array[i][0];
- Real thisU;
- for(i=end-1; i>=begin; i--){
- thisU = array[i][0];
- if(thisU < prevU)
- prevU = thisU;
- else
- break;
- }
- return i;
-}
-
-//if(V(start) == v, return start, other wise return the
-//last i so that V(i)==v
-Int vertexArray::skipEqualityFromStart(Real v, Int start, Int end)
-{
- Int i;
- if(array[start][1] != v)
- return start;
- //now array[start][1] == v
- for(i=start+1; i<= end; i++)
- if(array[i][1] != v)
- break;
- return i-1;
-}
-
-
-/***************************vertexArray end****************************************/
-
-
-
-/***************************relfex chain stuff begin here*****************************/
-
-reflexChain::reflexChain(Int size, Int is_increasing)
-{
- queue = (Real2*) malloc(sizeof(Real2) * size);
- assert(queue);
- index_queue = 0;
- size_queue = size;
- isIncreasing = is_increasing;
-}
-
-reflexChain::~reflexChain()
-{
- free(queue);
-}
-
-/*put (u,v) at the end of the queue
- *pay attention to space
- */
-void reflexChain::insert(Real u, Real v)
-{
- Int i;
- if(index_queue >= size_queue) {
- Real2 *temp = (Real2*) malloc(sizeof(Real2) * (2*size_queue+1));
- assert(temp);
-
- /*copy*/
- for(i=0; i<index_queue; i++){
- temp[i][0] = queue[i][0];
- temp[i][1] = queue[i][1];
- }
-
- free(queue);
- queue = temp;
- size_queue = 2*size_queue + 1;
- }
-
- queue[index_queue][0] = u;
- queue[index_queue][1] = v;
- index_queue ++;
-}
-
-void reflexChain::insert(Real v[2])
-{
- insert(v[0], v[1]);
-}
-
-/*
-static Real area(Real A[2], Real B[2], Real C[2])
-{
- Real Bx, By, Cx, Cy;
- Bx = B[0] - A[0];
- By = B[1] - A[1];
- Cx = C[0] - A[0];
- Cy = C[1] - A[1];
- return Bx*Cy - Cx*By;
-}
-*/
-
-/*the chain is reflex, and the vertex v is
- *on the other side of the chain, so that
- *we can outout the fan with v as the
- *the center
- */
-void reflexChain::outputFan(Real v[2], primStream* pStream)
-{
- Int i;
- pStream->begin();
- pStream->insert(v);
- if(isIncreasing) {
- for(i=0; i<index_queue; i++)
- pStream->insert(queue[i]);
- }
- else {
- for(i=index_queue-1; i>=0; i--)
- pStream->insert(queue[i]);
- }
- pStream->end(PRIMITIVE_STREAM_FAN);
-}
-
-void reflexChain::processNewVertex(Real v[2], primStream* pStream)
-{
- Int i,j,k;
- Int isReflex;
- /*if there are at most one vertex in the queue, then simply insert
- */
- if(index_queue <=1){
- insert(v);
- return;
- }
-
- /*there are at least two vertices in the queue*/
- j=index_queue-1;
-
- for(i=j; i>=1; i--) {
- if(isIncreasing) {
- isReflex = (area(queue[i-1], queue[i], v) <= 0.0);
- }
- else /*decreasing*/{
- isReflex = (area(v, queue[i], queue[i-1]) <= 0.0);
- }
- if(isReflex) {
- break;
- }
- }
-
- /*
- *if i<j then vertices: i+1--j are convex
- * output triangle fan:
- * v, and queue[i], i+1, ..., j
- */
- if(i<j)
- {
- pStream->begin();
- pStream->insert(v);
- if(isIncreasing) {
- for(k=i; k<=j; k++)
- pStream->insert(queue[k]);
- }
- else {
- for(k=j; k>=i; k--)
- pStream->insert(queue[k]);
- }
-
- pStream->end(PRIMITIVE_STREAM_FAN);
- }
-
- /*delete vertices i+1--j from the queue*/
- index_queue = i+1;
- /*finally insert v at the end of the queue*/
- insert(v);
-
-}
-
-void reflexChain::print()
-{
- Int i;
- printf("reflex chain: isIncreasing=%i\n", isIncreasing);
- for(i=0; i<index_queue; i++) {
- printf("(%f,%f) ", queue[i][0], queue[i][1]);
- }
- printf("\n");
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-#ifndef _MONO_TRIANGULATION_H
-#define _MONO_TRIANGULATION_H
-
-#include "definitions.h"
-#include "primitiveStream.h"
-#include "directedLine.h"
-#include "arc.h"
-
-class Backend;
-
-class reflexChain{
- Real2 *queue;
- /*the order of the polygon vertices: either q[0],q[1].., or
- * q[n-1], q[n-2], ..., q[0]
- *this order determines the interior of the polygon, so it
- *also used to determines whether a chain is reflex or convex
- */
- Int isIncreasing;
- Int index_queue;
- Int size_queue; /*allocated size*/
-
-public:
- reflexChain(Int size, Int isIncreasing);
- ~reflexChain();
-
- void insert(Real u, Real v);
- void insert(Real v[2]);
-
- void processNewVertex(Real v[2], primStream* pStream);
- void outputFan(Real v[2], primStream* pStream);
-
- void processNewVertex(Real v[2], Backend* backend);
- void outputFan(Real v[2], Backend* backend);
-
- void print();
-};
-
-/*dynamic array of pointers to reals.
- *Intended to store an array of (u,v).
- *Notice that it doesn't allocate or dealocate the space
- *for the (u,v) themselfs. So it assums that someone else
- *is taking care of them, while this class only plays with
- *the pointers.
- */
-class vertexArray{
- Real** array;
- Int index;
- Int size;
-public:
- vertexArray(Int s);
- vertexArray(Real vertices[][2], Int nVertices);
- ~vertexArray();
- void appendVertex(Real* ptr); /*the content (pointed by ptr is NOT copied*/
- Real* getVertex(Int i) {return array[i];}
- Real** getArray() {return array;}
- Int getNumElements() {return index;}
- Int findIndexAbove(Real v);
- Int findIndexAboveGen(Real v, Int startIndex, Int EndIndex);
- Int findIndexBelowGen(Real v, Int startIndex, Int EndIndex);
- Int findIndexStrictBelowGen(Real v, Int startIndex, Int EndIndex);
- Int findIndexFirstAboveEqualGen(Real v, Int startIndex, Int endIndex);
- Int skipEqualityFromStart(Real v, Int start, Int end);
- //return i such that fron [i+1, end] is strictly U-monotone (left to right
- Int findDecreaseChainFromEnd(Int begin, Int end);
- void print();
-};
-
-void monoTriangulation(directedLine* monoPolygon, primStream* pStream);
-
-void monoTriangulationRec(Real* topVertex, Real* botVertex,
- vertexArray* inc_chain, Int inc_current,
- vertexArray* dec_chain, Int dec_current,
- primStream* pStream);
-
-void monoTriangulationRec(directedLine* inc_chain, Int inc_index,
- directedLine* dec_chain, Int dec_index,
- directedLine* topVertex, Int top_index,
- directedLine* botVertex,
- primStream* pStream);
-
-/*the chain could be increasing or decreasing, although we use the
- * name inc_chain.
- *the argument is_increase_chain indicates whether this chain
- *is increasing (left chain in V-monotone case) or decreaing (right chain
- *in V-monotone case).
- */
-void monoTriangulation2(Real* topVertex, Real* botVertex,
- vertexArray* inc_chain, Int inc_smallIndex,
- Int inc_largeIndex,
- Int is_increase_chain,
- primStream* pStream);
-void monoTriangulationRecGen(Real* topVertex, Real* botVertex,
- vertexArray* inc_chain, Int inc_current, Int inc_end,
- vertexArray* dec_chain, Int dec_current, Int dec_end,
- primStream* pStream);
-
-void monoTriangulationRecGenOpt(Real* topVertex, Real* botVertex,
- vertexArray* inc_chain, Int inc_current, Int inc_end,
- vertexArray* dec_chain, Int dec_current, Int dec_end,
- primStream* pStream);
-
-void triangulateXYMonoTB(Int n_left, Real** leftVerts,
- Int n_right, Real** rightVerts,
- primStream* pStream);
-
-void monoTriangulationRecGenTBOpt(Real* topVertex, Real* botVertex,
- vertexArray* inc_chain, Int inc_current, Int inc_end,
- vertexArray* dec_chain, Int dec_current, Int dec_end,
- primStream* pStream);
-
-void monoTriangulationRecOpt(Real* topVertex, Real* botVertex,
- vertexArray* left_chain, Int left_current,
- vertexArray* right_chain, Int right_current,
- primStream* pStream);
-
-void monoTriangulationRecFunGen(Real* topVertex, Real* botVertex,
- vertexArray* inc_chain, Int inc_current, Int inc_end,
- vertexArray* dec_chain, Int dec_current, Int dec_end,
- Int (*compFun)(Real*, Real*),
- primStream* pStream);
-
-void monoTriangulationRecFun(Real* topVertex, Real* botVertex,
- vertexArray* inc_chain, Int inc_current,
- vertexArray* dec_chain, Int dec_current,
- Int (*compFun)(Real*, Real*),
- primStream* pStream);
-void monoTriangulationFun(directedLine* monoPolygon,
- Int (*compFun)(Real*, Real*), primStream* pStream);
-
-
-
-
-void monoTriangulationRec(Real* topVertex, Real* botVertex,
- vertexArray* inc_chain, Int inc_current,
- vertexArray* dec_chain, Int dec_current,
- Backend* backend);
-
-void monoTriangulationFunBackend(Arc_ptr loop, Int (*compFun)(Real*, Real*), Backend* backend);
-
-void monoTriangulationRecFunBackend(Real* topVertex, Real* botVertex,
- vertexArray* inc_chain, Int inc_current,
- vertexArray* dec_chain, Int dec_current,
- Int (*compFun)(Real*, Real*),
- Backend* backend);
-
-void monoTriangulationOpt(directedLine* poly, primStream* pStream);
-
-#endif
-
-
-
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * mystdio.h
- *
- */
-
-#ifndef __glumystdio_h_
-#define __glumystdio_h_
-
-#ifdef STANDALONE
-inline void _glu_dprintf( char *, ... ) { }
-#endif
-
-#ifdef LIBRARYBUILD
-#ifndef NDEBUG
-#include <stdio.h>
-#define _glu_dprintf printf
-#else
-inline void _glu_dprintf( char *, ... ) { }
-#endif
-#endif
-
-#ifdef GLBUILD
-inline void _glu_dprintf( char *, ... ) { }
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-#endif /* __glumystdio_h_ */
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-/*
- * mystdlib.h
- *
- */
-
-#ifndef __glumystdlib_h_
-#define __glumystdlib_h_
-
-#ifdef STANDALONE
-typedef unsigned int size_t;
-extern "C" void abort( void );
-extern "C" void * malloc( size_t );
-extern "C" void free( void * );
-#endif
-
-#ifdef LIBRARYBUILD
-#include <stdlib.h>
-#endif
-
-#ifdef GLBUILD
-typedef unsigned int size_t;
-extern "C" void abort( void );
-extern "C" void * malloc( size_t );
-extern "C" void free( void * );
-#endif
-
-#endif /* __glumystdlib_h_ */
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "partitionX.h"
-
-#define CONCAVITY_ZERO 1.0e-6 //this number is used to test whether a vertex is concave (refelx)
- //or not. The test needs to compute the area of the three adjacent
- //vertices to see if the are is positive or negative.
-
-Int isCuspX(directedLine *v)
-{
- //if v->prev <= v && v->next <= v
- //|| v->prev >= v && v->next >= v
- Real* T = v->head();
- Real* P = v->getPrev()->head();
- Real* N = v->getNext()->head();
- if(
- (compV2InX(T,P) != -1 &&
- compV2InX(T,N) != -1
- ) ||
- (compV2InX(T,P) != 1 &&
- compV2InX(T,N) != 1
- )
- )
- return 1;
- else
- return 0;
-}
-
-Int isReflexX(directedLine* v)
-{
- Real* A = v->getPrev()->head();
- Real* B = v->head();
- Real* C = v->tail();
- Real Bx,By, Cx, Cy;
- //scale them in case they are too small
- Bx = 10*(B[0] - A[0]);
- By = 10*(B[1] - A[1]);
- Cx = 10*(C[0] - A[0]);
- Cy = 10*(C[1] - A[1]);
-
- if(Bx*Cy - Cx*By < -CONCAVITY_ZERO) return 1;
- else return 0;
-}
-
-
-/*return
- *0: not-cusp
- *1: interior cusp
- *2: exterior cusp
- */
-Int cuspTypeX(directedLine *v)
-{
- if(! isCuspX(v)) return 0;
- else
- {
-//printf("isCusp,%f,%f\n", v->head()[0], v->head()[1]);
- if(isReflexX(v))
- {
-// printf("isReflex\n");
- return 1;
- }
- else
- {
-// printf("not isReflex\n");
- return 2;
- }
- }
-}
-
-Int numInteriorCuspsX(directedLine *polygon)
-{
- directedLine *temp;
- int ret = 0;
- if(cuspTypeX(polygon) == 1)
- ret++;
- for(temp = polygon->getNext(); temp != polygon; temp = temp->getNext())
- if(cuspTypeX(temp) == 1)
- ret++;
- return ret;
-}
-
-
-void findInteriorCuspsX(directedLine *polygon, Int& ret_n_interior_cusps,
- directedLine** ret_interior_cusps)
-{
- directedLine *temp;
- ret_n_interior_cusps = 0;
- if(cuspTypeX(polygon) == 1)
- {
- ret_interior_cusps[ret_n_interior_cusps++] = polygon;
- }
- for(temp = polygon->getNext(); temp != polygon; temp = temp->getNext())
- if(cuspTypeX(temp) == 1)
- {
- ret_interior_cusps[ret_n_interior_cusps++] = temp;
- }
-}
-
-directedLine* findDiagonal_singleCuspX(directedLine* cusp)
-{
- directedLine* temp;
- Int is_minimal = ((compV2InX(cusp->head(), cusp->tail()) == -1)? 1:0);
-
- if(is_minimal)
- for(temp = cusp->getNext(); temp != cusp; temp = temp->getNext())
- {
- if(compV2InX(cusp->head(), temp->head()) == 1)
- {
- return temp;
- }
- }
- else //is maxmal
- for(temp = cusp->getNext(); temp != cusp; temp = temp->getNext())
- {
- if(compV2InX(cusp->head(), temp->head()) == -1)
- {
- return temp;
- }
- }
- return NULL;
-}
-
-
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-#ifndef _PARTITIONX_H
-#define _PARTITIONX_H
-
-#include "directedLine.h"
-
-Int isCuspX(directedLine *v);
-Int isReflexX(directedLine *v);
-Int cuspTypeX(directedLine *v);
-
-//assuming the array of ret_interior_cusps has been allocated
-void findInteriorCuspsX(directedLine* polygon, Int& ret_n_interior_cusps,
- directedLine** ret_interior_cusps);
-
-Int numInteriorCuspsX(directedLine* polygon);
-
-/*a single polygon with a single cusp
- *return the diagonal vertex corresponding to this cusp
- */
-directedLine* findDiagonal_singleCuspX(directedLine* cusp);
-
-#endif
-
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-
-#include "zlassert.h"
-#include "partitionY.h"
-#include "searchTree.h"
-#include "quicksort.h"
-#include "polyUtil.h"
-
-
-#define max(a,b) ((a>b)? a:b)
-#define min(a,b) ((a>b)? b:a)
-
-
-/*retrurn
- *-1: if A < B (Ya<Yb) || (Ya==Yb)
- * 0: if A == B
- * 1: if A>B
- */
-static Int compVertInY(Real A[2], Real B[2])
-{
- if( (A[1] < B[1]) || (A[1]==B[1] && A[0]<B[0]))
- return -1;
- else if
- ( A[1] == B[1] && A[0] == B[0]) return 0;
- else
- return 1;
-}
-
-/*v is a vertex: the head of en edge,
- *e is an edge,
- *return 1 if e is below v: assume v1 and v2 are the two endpoints of e:
- * v1<= v, v2<=v.
- */
-Int isBelow(directedLine *v, directedLine *e)
-{
- Real* vert = v->head();
- if( compVertInY(e->head(), vert) != 1
- && compVertInY(e->tail(), vert) != 1
- )
- return 1;
- else
- return 0;
-}
-
-/*v is a vertex: the head of en edge,
- *e is an edge,
- *return 1 if e is below v: assume v1 and v2 are the two endpoints of e:
- * v1>= v, v2>=v.
- */
-Int isAbove(directedLine *v, directedLine *e)
-{
- Real* vert = v->head();
- if( compVertInY(e->head(), vert) != -1
- && compVertInY(e->tail(), vert) != -1
- )
- return 1;
- else
- return 0;
-}
-
-Int isCusp(directedLine *v)
-{
- Real *A=v->getPrev()->head();
- Real *B=v->head();
- Real *C=v->tail();
- if(A[1] < B[1] && B[1] < C[1])
- return 0;
- else if(A[1] > B[1] && B[1] > C[1])
- return 0;
- else if(A[1] < B[1] && C[1] < B[1])
- return 1;
- else if(A[1] > B[1] && C[1] > B[1])
- return 1;
-
- if((isAbove(v, v) && isAbove(v, v->getPrev())) ||
- (isBelow(v, v) && isBelow(v, v->getPrev())))
- return 1;
- else
- return 0;
-}
-
-/*crossproduct is strictly less than 0*/
-Int isReflex(directedLine *v)
-{
- Real* A = v->getPrev()->head();
- Real* B = v->head();
- Real* C = v->tail();
- Real Bx,By, Cx, Cy;
- Bx = B[0] - A[0];
- By = B[1] - A[1];
- Cx = C[0] - A[0];
- Cy = C[1] - A[1];
-
- if(Bx*Cy - Cx*By < 0) return 1;
- else return 0;
-}
-
- /*return
- *0: not-cusp
- *1: interior cusp
- *2: exterior cusp
- */
-Int cuspType(directedLine *v)
-{
- if(! isCusp(v)) return 0;
- else if(isReflex(v)) return 1;
- else
- return 2;
-}
-
-sweepRange* sweepRangeMake(directedLine* left, Int leftType,
- directedLine* right, Int rightType)
-{
- sweepRange* ret = (sweepRange*)malloc(sizeof(sweepRange));
- assert(ret);
- ret->left = left;
- ret->leftType = leftType;
- ret->right = right;
- ret->rightType = rightType;
- return ret;
-}
-
-void sweepRangeDelete(sweepRange* range)
-{
- free(range);
-}
-
-Int sweepRangeEqual(sweepRange* src1, sweepRange* src2)
-{
- Int leftEqual;
- Int rightEqual;
-
-
- /*The case when both are vertices should not happen*/
- assert(! (src1->leftType == 0 && src2->leftType == 0));
- if(src1->leftType == 0 && src2->leftType == 1){
- if(src1->left == src2->left ||
- src1->left->getPrev() == src2->left
- )
- leftEqual = 1;
- else
- leftEqual = 0;
- }
- else if(src1->leftType == 1 && src2->leftType == 1){
- if(src1->left == src2->left)
- leftEqual = 1;
- else
- leftEqual = 0;
- }
- else /*src1->leftType == 1 && src2->leftType == 0*/{
- if(src1->left == src2->left ||
- src1->left == src2->left->getPrev()
- )
- leftEqual = 1;
- else
- leftEqual = 0;
- }
-
- /*the same thing for right*/
- /*The case when both are vertices should not happen*/
- assert(! (src1->rightType == 0 && src2->rightType == 0));
- if(src1->rightType == 0 && src2->rightType == 1){
- if(src1->right == src2->right ||
- src1->right->getPrev() == src2->right
- )
- rightEqual = 1;
- else
- rightEqual = 0;
- }
- else if(src1->rightType == 1 && src2->rightType == 1){
- if(src1->right == src2->right)
- rightEqual = 1;
- else
- rightEqual = 0;
- }
- else /*src1->rightType == 1 && src2->rightType == 0*/{
- if(src1->right == src2->right ||
- src1->right == src2->right->getPrev()
- )
- rightEqual = 1;
- else
- rightEqual = 0;
- }
-
- return (leftEqual == 1 || rightEqual == 1);
-}
-
-/*given (x_1, y_1) and (x_2, y_2), and y
- *return x such that (x,y) is on the line
- */
-inline/*static*/ Real intersectHoriz(Real x1, Real y1, Real x2, Real y2, Real y)
-{
- return ((y2==y1)? (x1+x2)*Real(0.5) : x1 + ((y-y1)/(y2-y1)) * (x2-x1));
-/*
- if(y2 == y1) return (x1+x2)*0.5;
- else return x1 + ((y-y1)/(y2-y1)) * (x2-x1);
-*/
-}
-
-/*compare two edges of a polygon.
- *edge A < edge B if there is a horizontal line so that the intersection
- *with A is to the left of the intersection with B.
- *This function is used in sweepY for the dynamic search tree insertion to
- *order the edges.
- * Implementation: (x_1,y_1) and (x_2, y_2)
- */
-static Int compEdges(directedLine *e1, directedLine *e2)
-{
- Real* head1 = e1->head();
- Real* tail1 = e1->tail();
- Real* head2 = e2->head();
- Real* tail2 = e2->tail();
-/*
- Real h10 = head1[0];
- Real h11 = head1[1];
- Real t10 = tail1[0];
- Real t11 = tail1[1];
- Real h20 = head2[0];
- Real h21 = head2[1];
- Real t20 = tail2[0];
- Real t21 = tail2[1];
-*/
- Real e1_Ymax, e1_Ymin, e2_Ymax, e2_Ymin;
-/*
- if(h11>t11) {
- e1_Ymax= h11;
- e1_Ymin= t11;
- }
- else{
- e1_Ymax = t11;
- e1_Ymin = h11;
- }
-
- if(h21>t21) {
- e2_Ymax= h21;
- e2_Ymin= t21;
- }
- else{
- e2_Ymax = t21;
- e2_Ymin = h21;
- }
-*/
-
- if(head1[1]>tail1[1]) {
- e1_Ymax= head1[1];
- e1_Ymin= tail1[1];
- }
- else{
- e1_Ymax = tail1[1];
- e1_Ymin = head1[1];
- }
-
- if(head2[1]>tail2[1]) {
- e2_Ymax= head2[1];
- e2_Ymin= tail2[1];
- }
- else{
- e2_Ymax = tail2[1];
- e2_Ymin = head2[1];
- }
-
-
- /*Real e1_Ymax = max(head1[1], tail1[1]);*/ /*max(e1->head()[1], e1->tail()[1]);*/
- /*Real e1_Ymin = min(head1[1], tail1[1]);*/ /*min(e1->head()[1], e1->tail()[1]);*/
- /*Real e2_Ymax = max(head2[1], tail2[1]);*/ /*max(e2->head()[1], e2->tail()[1]);*/
- /*Real e2_Ymin = min(head2[1], tail2[1]);*/ /*min(e2->head()[1], e2->tail()[1]);*/
-
- Real Ymax = min(e1_Ymax, e2_Ymax);
- Real Ymin = max(e1_Ymin, e2_Ymin);
-
- Real y = Real(0.5)*(Ymax + Ymin);
-
-/* Real x1 = intersectHoriz(e1->head()[0], e1->head()[1], e1->tail()[0], e1->tail()[1], y);
- Real x2 = intersectHoriz(e2->head()[0], e2->head()[1], e2->tail()[0], e2->tail()[1], y);
-*/
-/*
- Real x1 = intersectHoriz(h10, h11, t10, t11, y);
- Real x2 = intersectHoriz(h20, h21, t20, t21, y);
-*/
- Real x1 = intersectHoriz(head1[0], head1[1], tail1[0], tail1[1], y);
- Real x2 = intersectHoriz(head2[0], head2[1], tail2[0], tail2[1], y);
-
- if(x1<= x2) return -1;
- else return 1;
-}
-
-/*used by sort precedures
- */
-static Int compInY(directedLine* v1, directedLine* v2)
-{
- return v1->compInY(v2);
-}
-
-void findDiagonals(Int total_num_edges, directedLine** sortedVertices, sweepRange** ranges, Int& num_diagonals, directedLine** diagonal_vertices)
-{
- Int i,j,k;
-
- k=0;
-
- for(i=0; i<total_num_edges; i++)
- {
- directedLine* vert =sortedVertices[i];
- directedLine* thisEdge = vert;
- directedLine* prevEdge = vert->getPrev();
-/*
-printf("find i=%i\n", i);
-printf("the vertex is\n");
-vert->printSingle();
-*/
- if(isBelow(vert, thisEdge) && isBelow(vert, prevEdge) && compEdges(prevEdge, thisEdge)<0)
- {
- /*this is an upward interior cusp*/
- diagonal_vertices[k++] = vert;
-
- for(j=i+1; j<total_num_edges; j++)
- if(sweepRangeEqual(ranges[i], ranges[j]))
- {
- diagonal_vertices[k++] = sortedVertices[j];
- break;
- }
- assert(j<total_num_edges);
-
-
- }
- else if(isAbove(vert, thisEdge) && isAbove(vert, prevEdge) && compEdges(prevEdge, thisEdge)>0)
- {
- /*this is an downward interior cusp*/
- diagonal_vertices[k++] = vert;
- for(j=i-1; j>=0; j--)
- if(sweepRangeEqual(ranges[i], ranges[j]))
- {
- diagonal_vertices[k++] = sortedVertices[j];
- break;
- }
-/* printf("j=%i\n", j);*/
- assert(j>=0);
-
-
-
- }
- }
- num_diagonals = k/2;
-}
-
-/*get rid of repeated diagonlas so that each diagonal appears only once in the array
- */
-Int deleteRepeatDiagonals(Int num_diagonals, directedLine** diagonal_vertices, directedLine** new_vertices)
-{
- Int i,k;
- Int j,l;
- Int index;
- index=0;
- for(i=0,k=0; i<num_diagonals; i++, k+=2)
- {
- Int isRepeated=0;
- /*check the diagonla (diagonal_vertice[k], diagonal_vertices[k+1])
- *is repeated or not
- */
- for(j=0,l=0; j<index; j++, l+=2)
- {
- if(
- (diagonal_vertices[k] == new_vertices[l] &&
- diagonal_vertices[k+1] == new_vertices[l+1]
- )
- ||
- (
- diagonal_vertices[k] == new_vertices[l+1] &&
- diagonal_vertices[k+1] == new_vertices[l]
- )
- )
- {
- isRepeated=1;
- break;
- }
- }
- if(! isRepeated)
- {
- new_vertices[index+index] = diagonal_vertices[k];
- new_vertices[index+index+1] = diagonal_vertices[k+1];
- index++;
- }
- }
- return index;
-}
-
-/*for debug only*/
-directedLine** DBGfindDiagonals(directedLine *polygons, Int& num_diagonals)
-{
- Int total_num_edges = 0;
- directedLine** array = polygons->toArrayAllPolygons(total_num_edges);
- quicksort( (void**)array, 0, total_num_edges-1, (Int (*)(void*, void*)) compInY);
- sweepRange** ranges = (sweepRange**) malloc(sizeof(sweepRange*) * total_num_edges);
- assert(ranges);
-
- sweepY(total_num_edges, array, ranges);
-
- directedLine** diagonal_vertices = (directedLine**) malloc(sizeof(directedLine*) * total_num_edges);
- assert(diagonal_vertices);
- findDiagonals(total_num_edges, array, ranges, num_diagonals, diagonal_vertices);
-
- num_diagonals=deleteRepeatDiagonals(num_diagonals, diagonal_vertices, diagonal_vertices);
- return diagonal_vertices;
-
-}
-
-
-/*partition into Y-monotone polygons*/
-directedLine* partitionY(directedLine *polygons, sampledLine **retSampledLines)
-{
- Int total_num_edges = 0;
- directedLine** array = polygons->toArrayAllPolygons(total_num_edges);
-
- quicksort( (void**)array, 0, total_num_edges-1, (Int (*)(void*, void*)) compInY);
-
- sweepRange** ranges = (sweepRange**) malloc(sizeof(sweepRange*) * (total_num_edges));
- assert(ranges);
-
-
-
- sweepY(total_num_edges, array, ranges);
-
-
-
- /*the diagonal vertices are stored as:
- *v0-v1: 1st diagonal
- *v2-v3: 2nd diagonal
- *v5-v5: 3rd diagonal
- *...
- */
-
-
- Int num_diagonals;
- /*number diagonals is < total_num_edges*total_num_edges*/
- directedLine** diagonal_vertices = (directedLine**) malloc(sizeof(directedLine*) * total_num_edges*2/*total_num_edges*/);
- assert(diagonal_vertices);
-
-
-
- findDiagonals(total_num_edges, array, ranges, num_diagonals, diagonal_vertices);
-
-
-
- directedLine* ret_polygons = polygons;
- sampledLine* newSampledLines = NULL;
- Int i,k;
-
-num_diagonals=deleteRepeatDiagonals(num_diagonals, diagonal_vertices, diagonal_vertices);
-
-
-
- Int *removedDiagonals=(Int*)malloc(sizeof(Int) * num_diagonals);
- for(i=0; i<num_diagonals; i++)
- removedDiagonals[i] = 0;
-
-
-
-
-
- for(i=0,k=0; i<num_diagonals; i++,k+=2)
- {
-
-
- directedLine* v1=diagonal_vertices[k];
- directedLine* v2=diagonal_vertices[k+1];
- directedLine* ret_p1;
- directedLine* ret_p2;
-
- /*we ahve to determine whether v1 and v2 belong to the same polygon before
- *their structure are modified by connectDiagonal().
- */
-/*
- directedLine *root1 = v1->findRoot();
- directedLine *root2 = v2->findRoot();
- assert(root1);
- assert(root2);
-*/
-
-directedLine* root1 = v1->rootLinkFindRoot();
-directedLine* root2 = v2->rootLinkFindRoot();
-
- if(root1 != root2)
- {
-
- removedDiagonals[i] = 1;
- sampledLine* generatedLine;
-
-
-
- v1->connectDiagonal(v1,v2, &ret_p1, &ret_p2, &generatedLine, ret_polygons);
-
-
-
- newSampledLines = generatedLine->insert(newSampledLines);
-/*
- ret_polygons = ret_polygons->cutoffPolygon(root1);
-
- ret_polygons = ret_polygons->cutoffPolygon(root2);
- ret_polygons = ret_p1->insertPolygon(ret_polygons);
-root1->rootLinkSet(ret_p1);
-root2->rootLinkSet(ret_p1);
-ret_p1->rootLinkSet(NULL);
-ret_p2->rootLinkSet(ret_p1);
-*/
- ret_polygons = ret_polygons->cutoffPolygon(root2);
-
-
-
-root2->rootLinkSet(root1);
-ret_p1->rootLinkSet(root1);
-ret_p2->rootLinkSet(root1);
-
- /*now that we have connected the diagonal v1 and v2,
- *we have to check those unprocessed diagonals which
- *have v1 or v2 as an end point. Notice that the head of v1
- *has the same coodinates as the head of v2->prev, and the head of
- *v2 has the same coordinate as the head of v1->prev.
- *Suppose these is a diagonal (v1, x). If (v1,x) is still a valid
- *diagonal, then x should be on the left hand side of the directed line: *v1->prev->head -- v1->head -- v1->tail. Otherwise, (v1,x) should be
- *replaced by (v2->prev, x), that is, x is on the left of
- * v2->prev->prev->head, v2->prev->head, v2->prev->tail.
- */
- Int ii, kk;
- for(ii=0, kk=0; ii<num_diagonals; ii++, kk+=2)
- if( removedDiagonals[ii]==0)
- {
- directedLine* d1=diagonal_vertices[kk];
- directedLine* d2=diagonal_vertices[kk+1];
- /*check d1, and replace diagonal_vertices[kk] if necessary*/
- if(d1 == v1) {
- /*check if d2 is to left of v1->prev->head:v1->head:v1->tail*/
- if(! pointLeft2Lines(v1->getPrev()->head(),
- v1->head(), v1->tail(), d2->head()))
- {
-/*
- assert(pointLeft2Lines(v2->getPrev()->getPrev()->head(),
- v2->getPrev()->head(),
- v2->getPrev()->tail(), d2->head()));
-*/
- diagonal_vertices[kk] = v2->getPrev();
- }
- }
- if(d1 == v2) {
- /*check if d2 is to left of v2->prev->head:v2->head:v2->tail*/
- if(! pointLeft2Lines(v2->getPrev()->head(),
- v2->head(), v2->tail(), d2->head()))
- {
-/*
- assert(pointLeft2Lines(v1->getPrev()->getPrev()->head(),
- v1->getPrev()->head(),
- v1->getPrev()->tail(), d2->head()));
-*/
- diagonal_vertices[kk] = v1->getPrev();
- }
- }
- /*check d2 and replace diagonal_vertices[k+1] if necessary*/
- if(d2 == v1) {
- /*check if d1 is to left of v1->prev->head:v1->head:v1->tail*/
- if(! pointLeft2Lines(v1->getPrev()->head(),
- v1->head(), v1->tail(), d1->head()))
- {
-/* assert(pointLeft2Lines(v2->getPrev()->getPrev()->head(),
- v2->getPrev()->head(),
- v2->getPrev()->tail(), d1->head()));
-*/
- diagonal_vertices[kk+1] = v2->getPrev();
- }
- }
- if(d2 == v2) {
- /*check if d1 is to left of v2->prev->head:v2->head:v2->tail*/
- if(! pointLeft2Lines(v2->getPrev()->head(),
- v2->head(), v2->tail(), d1->head()))
- {
-/* assert(pointLeft2Lines(v1->getPrev()->getPrev()->head(),
- v1->getPrev()->head(),
- v1->getPrev()->tail(), d1->head()));
-*/
- diagonal_vertices[kk+1] = v1->getPrev();
- }
- }
- }
-}/*end if (root1 not equal to root 2)*/
-}
-
- /*second pass, now all diagoals should belong to the same polygon*/
-
-
-
- for(i=0,k=0; i<num_diagonals; i++, k += 2)
- if(removedDiagonals[i] == 0)
- {
-
-
- directedLine* v1=diagonal_vertices[k];
- directedLine* v2=diagonal_vertices[k+1];
-
-
-
- directedLine* ret_p1;
- directedLine* ret_p2;
-
- /*we ahve to determine whether v1 and v2 belong to the same polygon before
- *their structure are modified by connectDiagonal().
- */
- directedLine *root1 = v1->findRoot();
-/*
- directedLine *root2 = v2->findRoot();
-
-
-
- assert(root1);
- assert(root2);
- assert(root1 == root2);
- */
- sampledLine* generatedLine;
-
-
-
- v1->connectDiagonal(v1,v2, &ret_p1, &ret_p2, &generatedLine, ret_polygons);
- newSampledLines = generatedLine->insert(newSampledLines);
-
- ret_polygons = ret_polygons->cutoffPolygon(root1);
-
- ret_polygons = ret_p1->insertPolygon(ret_polygons);
-
- ret_polygons = ret_p2->insertPolygon(ret_polygons);
-
-
-
- for(Int j=i+1; j<num_diagonals; j++)
- {
- if(removedDiagonals[j] ==0)
- {
-
- directedLine* temp1=diagonal_vertices[2*j];
- directedLine* temp2=diagonal_vertices[2*j+1];
- if(temp1==v1 || temp1==v2 || temp2==v1 || temp2==v2)
- if(! temp1->samePolygon(temp1, temp2))
- {
- /*if temp1 and temp2 are in different polygons,
- *then one of them must be v1 or v2.
- */
-
-
-
- assert(temp1==v1 || temp1 == v2 || temp2==v1 || temp2 ==v2);
- if(temp1==v1)
- {
- diagonal_vertices[2*j] = v2->getPrev();
- }
- if(temp2==v1)
- {
- diagonal_vertices[2*j+1] = v2->getPrev();
- }
- if(temp1==v2)
- {
- diagonal_vertices[2*j] = v1->getPrev();
- }
- if(temp2==v2)
- {
- diagonal_vertices[2*j+1] = v1->getPrev();
- }
- }
- }
- }
-
- }
-
- /*clean up spaces*/
- free(array);
- free(ranges);
- free(diagonal_vertices);
- free(removedDiagonals);
-
- *retSampledLines = newSampledLines;
- return ret_polygons;
-}
-
-/*given a set of simple polygons where the interior
- *is decided by left-hand principle,
- *return a range (sight) for each vertex. This is called
- *Trapezoidalization.
- */
-void sweepY(Int nVertices, directedLine** sortedVertices, sweepRange** ret_ranges)
-{
- Int i;
- /*for each vertex in the sorted list, update the binary search tree.
- *and store the range information for each vertex.
- */
- treeNode* searchTree = NULL;
- for(i=0; i<nVertices;i++)
- {
-
- directedLine* vert = sortedVertices[i];
-
- directedLine* thisEdge = vert;
- directedLine* prevEdge = vert->getPrev();
-
- if(isBelow(vert, thisEdge) && isAbove(vert, prevEdge))
- {
-
- /*case 1: this < v < prev
- *the polygon is going down at v, the interior is to
- *the right hand side.
- * find the edge to the right of thisEdge for right range.
- * delete thisEdge
- * insert prevEdge
- */
- treeNode* thisNode = TreeNodeFind(searchTree, thisEdge, ( Int (*) (void *, void *))compEdges);
- assert(thisNode);
-
- treeNode* succ = TreeNodeSuccessor(thisNode);
- assert(succ);
- searchTree = TreeNodeDeleteSingleNode(searchTree, thisNode);
- searchTree = TreeNodeInsert(searchTree, TreeNodeMake(prevEdge), ( Int (*) (void *, void *))compEdges);
-
-
- ret_ranges[i] = sweepRangeMake(vert, 0, (directedLine*) (succ->key), 1);
-
- }
- else if(isAbove(vert, thisEdge) && isBelow(vert, prevEdge))
- {
-
- /*case 2: this > v > prev
- *the polygon is going up at v, the interior is to
- *the left hand side.
- * find the edge to the left of thisEdge for left range.
- * delete prevEdge
- * insert thisEdge
- */
- treeNode* prevNode = TreeNodeFind(searchTree, prevEdge, ( Int (*) (void *, void *))compEdges);
- assert(prevNode);
- treeNode* pred = TreeNodePredecessor(prevNode);
- searchTree = TreeNodeDeleteSingleNode(searchTree, prevNode);
- searchTree = TreeNodeInsert(searchTree, TreeNodeMake(thisEdge), ( Int (*) (void *, void *))compEdges);
- ret_ranges[i] = sweepRangeMake((directedLine*)(pred->key), 1, vert, 0);
- }
- else if(isAbove(vert, thisEdge) && isAbove(vert, prevEdge))
- {
-
- /*case 3: insert both edges*/
- treeNode* thisNode = TreeNodeMake(thisEdge);
- treeNode* prevNode = TreeNodeMake(prevEdge);
- searchTree = TreeNodeInsert(searchTree, thisNode, ( Int (*) (void *, void *))compEdges);
- searchTree = TreeNodeInsert(searchTree, prevNode, ( Int (*) (void *, void *))compEdges);
- if(compEdges(thisEdge, prevEdge)<0) /*interior cusp*/
- {
-
- treeNode* leftEdge = TreeNodePredecessor(thisNode);
- treeNode* rightEdge = TreeNodeSuccessor(prevNode);
- ret_ranges[i] = sweepRangeMake( (directedLine*) leftEdge->key, 1,
- (directedLine*) rightEdge->key, 1
- );
- }
- else /*exterior cusp*/
- {
-
- ret_ranges[i] = sweepRangeMake( prevEdge, 1, thisEdge, 1);
- }
- }
- else if(isBelow(vert, thisEdge) && isBelow(vert, prevEdge))
- {
-
- /*case 4: delete both edges*/
- treeNode* thisNode = TreeNodeFind(searchTree, thisEdge, ( Int (*) (void *, void *))compEdges);
- treeNode* prevNode = TreeNodeFind(searchTree, prevEdge, ( Int (*) (void *, void *))compEdges);
- if(compEdges(thisEdge, prevEdge)>0) /*interior cusp*/
- {
- treeNode* leftEdge = TreeNodePredecessor(prevNode);
- treeNode* rightEdge = TreeNodeSuccessor(thisNode);
- ret_ranges[i] = sweepRangeMake( (directedLine*) leftEdge->key, 1,
- (directedLine*) rightEdge->key, 1
- );
- }
- else /*exterior cusp*/
- {
- ret_ranges[i] = sweepRangeMake( thisEdge, 1, prevEdge, 1);
- }
- searchTree = TreeNodeDeleteSingleNode(searchTree, thisNode);
- searchTree = TreeNodeDeleteSingleNode(searchTree, prevNode);
- }
- else
- {
- fprintf(stderr,"error in partitionY.C, invalid case\n");
- printf("vert is\n");
- vert->printSingle();
- printf("thisEdge is\n");
- thisEdge->printSingle();
- printf("prevEdge is\n");
- prevEdge->printSingle();
-
- exit(1);
- }
- }
-
- /*finaly clean up space: delete the search tree*/
- TreeNodeDeleteWholeTree(searchTree);
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
- *partitionY.h:
- *partition a polygon into a Y-monotone polygon:
- * A polygon is Y-monotone if the boundary can be split into two polygon chains
- *A and B such that each chain is Y-monotonic that is the intersection of any
- *horizontal line intersects each chain has at most one connected componenets
- * (empty, single point or a single line).
- *
- * A vertex is a cusp if both its ajacent vertices are either at or above v,
- *or both at or below v. In addition, at least one of the ajacent verteces is
- *strictly below or above v.
- * A vertex is a relex vertex if the internals angle is strictly greater than
- *180. In other words, if the signed area is negative:
- *(x1, y1), (x2, y2), (x3, y3) are the three vertices along a polygon, the
- *order is such that left hand side is inside the polygon. Then (x2,y2) is
- *reflex if:
- * (x2-x1, y2-y1) cross (x3-x1, y3-y1) <0.
- *A vertex is an interior cusp if it is a cusp and a reflex.
- *A vertex is an exterior cusp if it is a cusp but not a reflex.
- *
- */
-
-#ifndef _PARTITIONY_H
-#define _PARTITIONY_H
-
-#include "directedLine.h"
-
-/*whether an edge is below a vertex*/
-Int isBelow(directedLine *v, directedLine *e);
-
-/*whether an edge is above a vertex*/
-Int isAbove(directedLine *v, directedLine *e);
-
-/*not-cusp,
- *inerior cusp
- *exterior cusp
- */
-Int cuspType(directedLine *v);
-
-/*used in trapezoidalization*/
-typedef struct sweepRange{
- directedLine *left;
- Int leftType; /*either a vertex (leftType=0) or an edge (leftType =1) */
- directedLine *right;
- Int rightType; /*either a vertex (rightType=0) or an edge (rightType =1) */
-} sweepRange;
-
-sweepRange* sweepRangeMake(directedLine* left, Int leftType,
- directedLine* right, Int rightType);
-
-void sweepRangeDelete(sweepRange* range);
-Int sweepRangeEqual(sweepRange* sr1, sweepRange* sr2);
-
-/*given a set of simple polygons where the interior
- *is decided by left-hand principle,
- *return a range (sight) for each vertex. This is called
- *Trapezoidalization.
- */
-void sweepY(Int nVertices, directedLine **sortedVerteces, sweepRange** ret_ranges);
-
-
-directedLine* partitionY(directedLine *polygons, sampledLine **retSampledLines);
-
-void findDiagonals(Int total_num_edges, directedLine** sortedVertices, sweepRange** ranges, Int& num_diagonals, directedLine** diagonal_vertices);
-
-directedLine** DBGfindDiagonals(directedLine *polygons, Int& num_diagonals);
-
-#endif
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-#include "zlassert.h"
-#include "polyDBG.h"
-
-#ifdef __WATCOMC__
-#pragma warning 14 10
-#pragma warning 391 10
-#pragma warning 726 10
-#endif
-
-static Real area(Real A[2], Real B[2], Real C[2])
-{
- Real Bx, By, Cx, Cy;
- Bx = B[0] - A[0];
- By = B[1] - A[1];
- Cx = C[0] - A[0];
- Cy = C[1] - A[1];
- return Bx*Cy - Cx*By;
-}
-
-Int DBG_isConvex(directedLine *poly)
-{
- directedLine* temp;
- if(area(poly->head(), poly->tail(), poly->getNext()->tail()) < 0.00000)
- return 0;
- for(temp = poly->getNext(); temp != poly; temp = temp->getNext())
- {
- if(area(temp->head(), temp->tail(), temp->getNext()->tail()) < 0.00000)
- return 0;
- }
- return 1;
-}
-
-Int DBG_is_U_monotone(directedLine* poly)
-{
- Int n_changes = 0;
- Int prev_sign;
- Int cur_sign;
- directedLine* temp;
- cur_sign = compV2InX(poly->tail(), poly->head());
-
- n_changes = (compV2InX(poly->getPrev()->tail(), poly->getPrev()->head())
- != cur_sign);
-
- for(temp = poly->getNext(); temp != poly; temp = temp->getNext())
- {
- prev_sign = cur_sign;
- cur_sign = compV2InX(temp->tail(), temp->head());
-
- if(cur_sign != prev_sign)
- n_changes++;
- }
-
- if(n_changes ==2) return 1;
- else return 0;
-}
-
-/*if u-monotone, and there is a long horizontal edge*/
-Int DBG_is_U_direction(directedLine* poly)
-{
-/*
- if(! DBG_is_U_monotone(poly))
- return 0;
-*/
- Int V_count = 0;
- Int U_count = 0;
- directedLine* temp;
- if( fabs(poly->head()[0] - poly->tail()[0]) <= fabs(poly->head()[1]-poly->tail()[1]))
- V_count += poly->get_npoints();
- else
- U_count += poly->get_npoints();
- /*
- else if(poly->head()[1] == poly->tail()[1])
- U_count += poly->get_npoints();
- */
- for(temp = poly->getNext(); temp != poly; temp = temp->getNext())
- {
- if( fabs(temp->head()[0] - temp->tail()[0]) <= fabs(temp->head()[1]-temp->tail()[1]))
- V_count += temp->get_npoints();
- else
- U_count += temp->get_npoints();
- /*
- if(temp->head()[0] == temp->tail()[0])
- V_count += temp->get_npoints();
- else if(temp->head()[1] == temp->tail()[1])
- U_count += temp->get_npoints();
- */
- }
-
- if(U_count > V_count) return 1;
- else return 0;
-}
-
-/*given two line segments, determine whether
- *they intersect each other or not.
- *return 1 if they do,
- *return 0 otherwise
- */
-Int DBG_edgesIntersect(directedLine* l1, directedLine* l2)
-{
- if(l1->getNext() == l2)
- {
- if(area(l1->head(), l1->tail(), l2->tail()) == 0) //colinear
- {
- if( (l1->tail()[0] - l1->head()[0])*(l2->tail()[0]-l2->head()[0]) +
- (l1->tail()[1] - l1->head()[1])*(l2->tail()[1]-l2->head()[1]) >=0)
- return 0; //not intersect
- else
- return 1;
- }
- //else we use the normal code
- }
- else if(l1->getPrev() == l2)
- {
- if(area(l2->head(), l2->tail(), l1->tail()) == 0) //colinear
- {
- if( (l2->tail()[0] - l2->head()[0])*(l1->tail()[0]-l1->head()[0]) +
- (l2->tail()[1] - l2->head()[1])*(l1->tail()[1]-l1->head()[1]) >=0)
- return 0; //not intersect
- else
- return 1;
- }
- //else we use the normal code
- }
- else //the two edges are not connected
- {
- if((l1->head()[0] == l2->head()[0] &&
- l1->head()[1] == l2->head()[1]) ||
- (l1->tail()[0] == l2->tail()[0] &&
- l1->tail()[1] == l2->tail()[1]))
- return 1;
-
- }
-
-
- if(
- (
- area(l1->head(), l1->tail(), l2->head())
- *
- area(l1->head(), l1->tail(), l2->tail())
- < 0
- )
- &&
- (
- area(l2->head(), l2->tail(), l1->head())
- *area(l2->head(), l2->tail(), l1->tail())
- < 0
- )
- )
- return 1;
- else
- return 0;
-}
-
-/*whether AB and CD intersect
- *return 1 if they do
- *retur 0 otheriwse
- */
-Int DBG_edgesIntersectGen(Real A[2], Real B[2], Real C[2], Real D[2])
-{
- if(
- (
- area(A, B, C) * area(A,B,D) <0
- )
- &&
- (
- area(C,D,A) * area(C,D,B) < 0
- )
- )
- return 1;
- else
- return 0;
-}
-
-/*determien whether (A,B) interesect chain[start] to [end]
- */
-Int DBG_intersectChain(vertexArray* chain, Int start, Int end, Real A[2], Real B[2])
-{
- Int i;
- for(i=start; i<=end-2; i++)
- if(DBG_edgesIntersectGen(chain->getVertex(i), chain->getVertex(i+1), A, B))
- return 1;
-
- return 0;
-}
-
-/*determine whether a polygon intersect itself or not
- *return 1 is it does,
- * 0 otherwise
- */
-Int DBG_polygonSelfIntersect(directedLine* poly)
-{
- directedLine* temp1;
- directedLine* temp2;
- temp1=poly;
- for(temp2=temp1->getNext(); temp2 != temp1; temp2=temp2->getNext())
- {
- if(DBG_edgesIntersect(temp1, temp2))
- {
- return 1;
- }
-
- }
-
- for(temp1=poly->getNext(); temp1 != poly; temp1 = temp1->getNext())
- for(temp2=temp1->getNext(); temp2 != temp1; temp2=temp2->getNext())
- {
- if(DBG_edgesIntersect(temp1, temp2))
- {
- return 1;
- }
- }
- return 0;
-}
-
-/*check whether a line segment intersects a polygon
- */
-Int DBG_edgeIntersectPoly(directedLine* edge, directedLine* poly)
-{
- directedLine* temp;
- if(DBG_edgesIntersect(edge, poly))
- return 1;
- for(temp=poly->getNext(); temp != poly; temp=temp->getNext())
- if(DBG_edgesIntersect(edge, temp))
- return 1;
- return 0;
-}
-
-/*check whether two polygons intersect
- */
-Int DBG_polygonsIntersect(directedLine* p1, directedLine* p2)
-{
- directedLine* temp;
- if(DBG_edgeIntersectPoly(p1, p2))
- return 1;
- for(temp=p1->getNext(); temp!= p1; temp = temp->getNext())
- if(DBG_edgeIntersectPoly(temp, p2))
- return 1;
- return 0;
-}
-
-/*check whether there are polygons intersecting each other in
- *a list of polygons
- */
-Int DBG_polygonListIntersect(directedLine* pList)
-{
- directedLine *temp;
- for(temp=pList; temp != NULL; temp = temp->getNextPolygon())
- if(DBG_polygonSelfIntersect(temp))
- return 1;
- directedLine* temp2;
- for(temp=pList; temp!=NULL; temp=temp->getNextPolygon())
- {
- for(temp2=temp->getNextPolygon(); temp2 != NULL; temp2=temp2->getNextPolygon())
- if(DBG_polygonsIntersect(temp, temp2))
- return 1;
- }
-
- return 0;
-}
-
-
-Int DBG_isCounterclockwise(directedLine* poly)
-{
- return (poly->polyArea() > 0);
-}
-
-/*ray: v0 with direction (dx,dy).
- *edge: v1-v2.
- * the extra point v10[2] is given for the information at
- *v1. Basically this edge is connectd to edge
- * v10-v1. If v1 is on the ray,
- * then we need v10 to determine whether this ray intersects
- * the edge or not (that is, return 1 or return 0).
- * If v1 is on the ray, then if v2 and v10 are on the same side of the ray,
- * we return 0, otherwise return 1.
- *For v2, if v2 is on the ray, we always return 0.
- *Notice that v1 and v2 are not symmetric. So the edge is directed!!!
- * The purpose for this convention is such that: a point is inside a polygon
- * if and only if it intersets with odd number of edges.
- */
-Int DBG_rayIntersectEdge(Real v0[2], Real dx, Real dy, Real v10[2], Real v1[2], Real v2[2])
-{
-/*
-if( (v1[1] >= v0[1] && v2[1]<= v0[1] )
- ||(v2[1] >= v0[1] && v1[1]<= v0[1] )
- )
- printf("rayIntersectEdge, *********\n");
-*/
-
- Real denom = (v2[0]-v1[0])*(-dy) - (v2[1]-v1[1]) * (-dx);
- Real nomRay = (v2[0]-v1[0]) * (v0[1] - v1[1]) - (v2[1]-v1[1])*(v0[0]-v1[0]);
- Real nomEdge = (v0[0]-v1[0]) * (-dy) - (v0[1]-v1[1])*(-dx);
-
-
- /*if the ray is parallel to the edge, return 0: not intersect*/
- if(denom == 0.0)
- return 0;
-
- /*if v0 is on the edge, return 0: not intersect*/
- if(nomRay == 0.0)
- return 0;
-
- /*if v1 is on the positive ray, and the neighbor of v1 crosses the ray
- *return 1: intersect
- */
- if(nomEdge == 0)
- { /*v1 is on the positive or negative ray*/
-
-/*
- printf("v1 is on the ray\n");
-*/
-
- if(dx*(v1[0]-v0[0])>=0 && dy*(v1[1]-v0[1])>=0) /*v1 on positive ray*/
- {
- if(area(v0, v1, v10) * area(v0, v1, v2) >0)
- return 0;
- else
- return 1;
- }
- else /*v1 on negative ray*/
- return 0;
- }
-
- /*if v2 is on the ray, always return 0: not intersect*/
- if(nomEdge == denom) {
-/* printf("v2 is on the ray\n");*/
- return 0;
- }
-
- /*finally */
- if(denom*nomRay>0 && denom*nomEdge>0 && nomEdge/denom <=1.0)
- return 1;
- return 0;
-}
-
-
-/*return the number of intersections*/
-Int DBG_rayIntersectPoly(Real v0[2], Real dx, Real dy, directedLine* poly)
-{
- directedLine* temp;
- Int count=0;
- if(DBG_rayIntersectEdge(v0, dx, dy, poly->getPrev()->head(), poly->head(), poly->tail()))
- count++;
-
- for(temp=poly->getNext(); temp != poly; temp = temp->getNext())
- if(DBG_rayIntersectEdge(v0, dx, dy, temp->getPrev()->head(), temp->head(), temp->tail()))
- count++;
-/*printf("ray intersect poly: count=%i\n", count);*/
- return count;
-}
-
-Int DBG_pointInsidePoly(Real v[2], directedLine* poly)
-{
-/*
-printf("enter pointInsidePoly , v=(%f,%f)\n", v[0], v[1]);
-printf("the polygon is\n");
-poly->printList();
-*/
- /*for debug purpose*/
- assert( (DBG_rayIntersectPoly(v,1,0,poly) % 2 )
- == (DBG_rayIntersectPoly(v,1,Real(0.1234), poly) % 2 )
- );
- if(DBG_rayIntersectPoly(v, 1, 0, poly) % 2 == 1)
- return 1;
- else
- return 0;
-}
-
-/*return the number of polygons which contain thie polygon
- * as a subset
- */
-Int DBG_enclosingPolygons(directedLine* poly, directedLine* list)
-{
- directedLine* temp;
- Int count=0;
-/*
-printf("%i\n", DBG_pointInsidePoly(poly->head(),
- list->getNextPolygon()
- ->getNextPolygon()
- ->getNextPolygon()
- ->getNextPolygon()
-));
-*/
-
- for(temp = list; temp != NULL; temp = temp->getNextPolygon())
- {
- if(poly != temp)
- if(DBG_pointInsidePoly(poly->head(), temp))
- count++;
-/* printf("count=%i\n", count);*/
- }
- return count;
-}
-
-void DBG_reverse(directedLine* poly)
-{
- if(poly->getDirection() == INCREASING)
- poly->putDirection(DECREASING);
- else
- poly->putDirection(INCREASING);
-
- directedLine* oldNext = poly->getNext();
- poly->putNext(poly->getPrev());
- poly->putPrev(oldNext);
-
- directedLine* temp;
- for(temp=oldNext; temp!=poly; temp = oldNext)
- {
- if(temp->getDirection() == INCREASING)
- temp->putDirection(DECREASING);
- else
- temp->putDirection(INCREASING);
-
- oldNext = temp->getNext();
- temp->putNext(temp->getPrev());
- temp->putPrev(oldNext);
- }
- printf("reverse done\n");
-}
-
-Int DBG_checkConnectivity(directedLine *polygon)
-{
- if(polygon == NULL) return 1;
- directedLine* temp;
- if(polygon->head()[0] != polygon->getPrev()->tail()[0] ||
- polygon->head()[1] != polygon->getPrev()->tail()[1])
- return 0;
- for(temp=polygon->getNext(); temp != polygon; temp=temp->getNext())
- {
- if(temp->head()[0] != temp->getPrev()->tail()[0] ||
- temp->head()[1] != temp->getPrev()->tail()[1])
- return 0;
- }
- return 1;
-}
-
-/*print out error message.
- *If it cannot modify the polygon list to make it satify the
- *requirements, return 1.
- *otherwise modify the polygon list, and return 0
- */
-Int DBG_check(directedLine *polyList)
-{
- directedLine* temp;
- if(polyList == NULL) return 0;
-
- /*if there are intersections, print out error message
- */
- if(DBG_polygonListIntersect(polyList))
- {
- fprintf(stderr, "DBG_check: there are self intersections, don't know to modify the polygons\n");
- return 1;
- }
-
- /*check the connectivity of each polygon*/
- for(temp = polyList; temp!= NULL; temp = temp ->getNextPolygon())
- {
- if(! DBG_checkConnectivity(temp))
- {
- fprintf(stderr, "DBG_check, polygon not connected\n");
- return 1;
- }
- }
-
- /*check the orientation of each polygon*/
- for(temp = polyList; temp!= NULL; temp = temp ->getNextPolygon())
- {
-
-
- Int correctDir;
-
- if( DBG_enclosingPolygons(temp, polyList) % 2 == 0)
- correctDir = 1; /*counterclockwise*/
- else
- correctDir = 0; /*clockwise*/
-
- Int actualDir = DBG_isCounterclockwise(temp);
-
- if(correctDir != actualDir)
- {
- fprintf(stderr, "DBG_check: polygon with incorrect orientations. reversed\n");
-
- DBG_reverse(temp);
- }
-
- }
- return 0;
-}
-
-/**************handle self intersections*****************/
-//determine whether e interects [begin, end] or not
-static directedLine* DBG_edgeIntersectChainD(directedLine *e,
- directedLine *begin, directedLine *end)
-{
- directedLine *temp;
- for(temp=begin; temp != end; temp = temp->getNext())
- {
- if(DBG_edgesIntersect(e, temp))
- return temp;
- }
- if(DBG_edgesIntersect(e, end))
- return end;
- return NULL;
-}
-
-//given a polygon, cut the edges off and finally obtain a
-//a polygon without intersections. The cut-off edges are
-//dealloated. The new polygon is returned.
-directedLine* DBG_cutIntersectionPoly(directedLine *polygon, int& cutOccur)
-{
- directedLine *begin, *end, *next;
- begin = polygon;
- end = polygon;
- cutOccur = 0;
- while( (next = end->getNext()) != begin)
- {
- directedLine *interc = NULL;
- if( (interc = DBG_edgeIntersectChainD(next, begin, end)))
- {
- int fixed = 0;
- if(DBG_edgesIntersect(next, interc->getNext()))
- {
- //trying to fix it
- Real buf[2];
- int i;
- Int n=5;
- buf[0] = interc->tail()[0];
- buf[1] = interc->tail()[1];
-
- for(i=1; i<n; i++)
- {
- Real r = ((Real)i) / ((Real) n);
- Real u = (1-r) * interc->head()[0] + r * interc->tail()[0];
- Real v = (1-r) * interc->head()[1] + r * interc->tail()[1];
- interc->tail()[0] = interc->getNext()->head()[0] = u;
- interc->tail()[1] = interc->getNext()->head()[1] = v;
- if( (! DBG_edgesIntersect(next, interc)) &&
- (! DBG_edgesIntersect(next, interc->getNext())))
- break; //we fixed it
- }
- if(i==n) // we didn't fix it
- {
- fixed = 0;
- //back to original
- interc->tail()[0] = interc->getNext()->head()[0] = buf[0];
- interc->tail()[1] = interc->getNext()->head()[1] = buf[1];
- }
- else
- {
- fixed = 1;
- }
- }
- if(fixed == 0)
- {
- cutOccur = 1;
- begin->deleteSingleLine(next);
-
- if(begin != end)
- {
- if(DBG_polygonSelfIntersect(begin))
- {
- directedLine* newEnd = end->getPrev();
- begin->deleteSingleLine(end);
- end = newEnd;
- }
- }
- }
- else
- {
- end = end->getNext();
- }
- }
- else
- {
- end = end->getNext();
- }
- }
- return begin;
-}
-
-//given a polygon, cut the edges off and finally obtain a
-//a polygon without intersections. The cut-off edges are
-//dealloated. The new polygon is returned.
-#if 0 // UNUSED
-static directedLine* DBG_cutIntersectionPoly_notwork(directedLine *polygon)
-{
- directedLine *crt;//current polygon
- directedLine *begin;
- directedLine *end;
- directedLine *temp;
- crt = polygon;
- int find=0;
- while(1)
- {
-//printf("loop\n");
- //if there are less than 3 edges, we should stop
- if(crt->getPrev()->getPrev() == crt)
- return NULL;
-
- if(DBG_edgesIntersect(crt, crt->getNext()) ||
- (crt->head()[0] == crt->getNext()->tail()[0] &&
- crt->head()[1] == crt->getNext()->tail()[1])
- )
- {
- find = 1;
- crt=crt->deleteChain(crt, crt->getNext());
- }
- else
- {
- //now we know crt and crt->getNext do not intersect
- begin = crt;
- end = crt->getNext();
-//printf("begin=(%f,%f)\n", begin->head()[0], begin->head()[1]);
-//printf("end=(%f,%f)\n", end->head()[0], end->head()[1]);
- for(temp=end->getNext(); temp!=begin; temp= temp->getNext())
- {
-//printf("temp=(%f,%f)\n", temp->head()[0], temp->head()[1]);
- directedLine *intersect = DBG_edgeIntersectChainD(temp, begin, end);
- if(intersect != NULL)
- {
- crt = crt->deleteChain(intersect, temp);
- find=1;
- break; //the for loop
- }
- else
- {
- end = temp;
- }
- }
- }
- if(find == 0)
- return crt;
- else
- find = 0; //go to next loop
-}
-}
-#endif
-
-directedLine* DBG_cutIntersectionAllPoly(directedLine* list)
-{
- directedLine* temp;
- directedLine* tempNext=NULL;
- directedLine* ret = NULL;
- int cutOccur=0;
- for(temp=list; temp != NULL; temp = tempNext)
- {
- directedLine *left;
- tempNext = temp->getNextPolygon();
-
- left = DBG_cutIntersectionPoly(temp, cutOccur);
- if(left != NULL)
- ret=left->insertPolygon(ret);
- }
- return ret;
-}
-
-sampledLine* DBG_collectSampledLinesAllPoly(directedLine *polygonList)
-{
- directedLine *temp;
- sampledLine* tempHead = NULL;
- sampledLine* tempTail = NULL;
- sampledLine* cHead = NULL;
- sampledLine* cTail = NULL;
-
- if(polygonList == NULL)
- return NULL;
-
- DBG_collectSampledLinesPoly(polygonList, cHead, cTail);
-
- assert(cHead);
- assert(cTail);
- for(temp = polygonList->getNextPolygon(); temp != NULL; temp = temp->getNextPolygon())
- {
- DBG_collectSampledLinesPoly(temp, tempHead, tempTail);
- cTail->insert(tempHead);
- cTail = tempTail;
- }
- return cHead;
-}
-
-void DBG_collectSampledLinesPoly(directedLine *polygon, sampledLine*& retHead, sampledLine*& retTail)
-{
- directedLine *temp;
- retHead = NULL;
- retTail = NULL;
- if(polygon == NULL)
- return;
-
- retHead = retTail = polygon->getSampledLine();
- for(temp = polygon->getNext(); temp != polygon; temp=temp->getNext())
- {
- retHead = temp->getSampledLine()->insert(retHead);
- }
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-#ifndef _POLYDBG_H
-#define _POLYDBG_H
-
-#include "definitions.h"
-#include "directedLine.h"
-#include "monoTriangulation.h"
-
-Int DBG_edgesIntersectGen(Real A[2], Real B[2], Real C[2], Real D[2]);
-Int DBG_intersectChain(vertexArray* chain, Int start, Int end, Real A[2], Real B[2]);
-
-
-Int DBG_edgesIntersect(directedLine* l1, directedLine* l2);
-Int DBG_polygonSelfIntersect(directedLine* poly);
-Int DBG_edgeIntersectPoly(directedLine* edge, directedLine* poly);
-Int DBG_polygonsIntersect(directedLine* p1, directedLine* p2);
-Int DBG_polygonListIntersect(directedLine* pList);
-
-Int DBG_isCounterclockwise(directedLine* poly);
-Int DBG_rayIntersectEdge(Real v0[2], Real dx, Real dy, Real v10[2], Real v1[2], Real v2[2]);
-Int DBG_pointInsidePoly(Real v[2], directedLine* poly);
-Int DBG_enclosingPolygons(directedLine* poly, directedLine* list);
-void DBG_reverse(directedLine* poly);
-Int DBG_check(directedLine *polyList);
-
-Int DBG_isConvex(directedLine *poly);
-Int DBG_is_U_direction(directedLine *poly);
-Int DBG_is_U_monotone(directedLine* poly);
-
-directedLine* DBG_cutIntersectionAllPoly(directedLine* list);
-directedLine* DBG_cutIntersectionPoly(directedLine *polygon, int& cutOccur);
-
-sampledLine* DBG_collectSampledLinesAllPoly(directedLine *polygonList);
-
-void DBG_collectSampledLinesPoly(directedLine *polygon, sampledLine*& retHead, sampledLine*& retTail);
-
-#endif
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "polyUtil.h"
-
-Real area(Real A[2], Real B[2], Real C[2])
-{
- Real Bx, By, Cx, Cy;
- Bx = B[0] - A[0];
- By = B[1] - A[1];
- Cx = C[0] - A[0];
- Cy = C[1] - A[1];
- return Bx*Cy - Cx*By;
-
-/* return (B[0]-A[0])*(C[1]-A[1]) - (C[0]-A[0])*(B[1]-A[1]);*/
-}
-
-/*given a directed line A->B, and a point P,
- *determine whether P is to the left of AB.
- *the line A->B (imagine it has beedn extended both
- *end to the infinity) divides the plan into two
- *half planes. When we walk from A to B, one
- *half is to the left and the other half is to the right.
- *return 1 if P is to the left.
- *if P is on AB, 0 is returned.
- */
-Int pointLeftLine(Real A[2], Real B[2], Real P[2])
-{
- if(area(A, B, P) >0) return 1;
- else return 0;
-}
-
-/*given two directed line: A -> B -> C, and another point P.
- *determine whether P is to the left hand side of A->B->C.
- *Think of BA and BC extended as two rays. So that the plane is
- * divided into two parts. One part is to the left we walk from A
- *to B and to C, the other part is to the right.
- * In order for P to be the left, P must be either to the left
- *of
- */
-Int pointLeft2Lines(Real A[2], Real B[2], Real C[2], Real P[2])
-{
- Int C_left_AB = (area(A, B, C)>0);
- Int P_left_AB = (area(A, B, P)>0);
- Int P_left_BC = (area(B, C, P)>0);
-
- if(C_left_AB)
- {
- return (P_left_AB && P_left_BC);
- }
- else
- return (P_left_AB || P_left_BC);
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-#ifndef _POLYUTIL_H
-#define _POLYUTIL_H
-
-#include "definitions.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-Real area(Real A[2], Real B[2], Real C[2]);
-
-Int pointLeftLine(Real A[2], Real B[2], Real P[2]);
-Int pointLeft2Lines(Real A[2], Real B[2], Real C[2], Real P[2]);
-#ifdef __cplusplus
-}
-#endif
-#endif
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include "gluos.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-#include <GL/gl.h>
-
-#include "primitiveStream.h"
-
-Int primStream::num_triangles()
-{
- Int i;
- Int ret=0;
- for(i=0; i<index_lengths; i++)
- {
- ret += lengths[i]-2;
- }
- return ret;
-}
-
-
-
-/*the begining of inserting a new primitive.
- *reset counter to be 0.
- */
-void primStream::begin()
-{
- counter = 0;
-}
-
-void primStream::insert(Real u, Real v)
-{
- /*if the space cannot hold u and v,
- *we have to expand the array
- */
- if(index_vertices+1 >= size_vertices) {
- Real* temp = (Real*) malloc (sizeof(Real) * (2*size_vertices + 2));
- assert(temp);
-
- /*copy*/
- for(Int i=0; i<index_vertices; i++)
- temp[i] = vertices[i];
-
- free(vertices);
- vertices = temp;
- size_vertices = 2*size_vertices + 2;
- }
-
- vertices[index_vertices++] = u;
- vertices[index_vertices++] = v;
- counter++;
-}
-
-/*the end of a primitive.
- *increase index_lengths
- */
-void primStream::end(Int type)
-{
- Int i;
- /*if there is no vertex in this primitive,
- *nothing needs to be done
- */
- if(counter == 0) return ;
-
- if(index_lengths >= size_lengths){
- Int* temp = (Int*) malloc(sizeof(Int) * (2*size_lengths + 2));
- assert(temp);
- Int* tempTypes = (Int*) malloc(sizeof(Int) * (2*size_lengths + 2));
- assert(tempTypes);
-
- /*copy*/
- for(i=0; i<index_lengths; i++){
- temp[i] = lengths[i];
- tempTypes[i] = types[i];
- }
-
- free(lengths);
- free(types);
- lengths = temp;
- types = tempTypes;
- size_lengths = 2*size_lengths + 2;
- }
- lengths[index_lengths] = counter;
- types[index_lengths] = type;
- index_lengths++;
-}
-
-void primStream::print()
-{
- Int i,j,k;
- printf("index_lengths=%i,size_lengths=%i\n", index_lengths, size_lengths);
- printf("index_vertices=%i,size_vertices=%i\n", index_vertices, size_vertices);
- k=0;
- for(i=0; i<index_lengths; i++)
- {
- if(types[i] == PRIMITIVE_STREAM_FAN)
- printf("primitive-FAN:\n");
- else
- printf("primitive-STRIP:\n");
- for(j=0; j<lengths[i]; j++)
- {
- printf("(%f,%f) ", vertices[k], vertices[k+1]);
- k += 2;
- }
- printf("\n");
- }
-}
-
-primStream::primStream(Int sizeLengths, Int sizeVertices)
-{
- lengths = (Int*)malloc (sizeof(Int) * sizeLengths);
- assert(lengths);
- types = (Int*)malloc (sizeof(Int) * sizeLengths);
- assert(types);
-
- vertices = (Real*) malloc(sizeof(Real) * sizeVertices);
- assert(vertices);
-
- index_lengths = 0;
- index_vertices = 0;
- size_lengths = sizeLengths;
- size_vertices = sizeVertices;
-
- counter = 0;
-}
-
-primStream::~primStream()
-{
- free(lengths);
- free(types);
- free(vertices);
-}
-
-void primStream::draw()
-{
- Int i,j,k;
- k=0;
- for(i=0; i<index_lengths; i++)
- {
- switch(types[i]){
- case PRIMITIVE_STREAM_FAN:
- glBegin(GL_TRIANGLE_FAN);
- break;
- case PRIMITIVE_STREAM_STRIP:
- glBegin(GL_TRIANGLE_STRIP);
- break;
- }
-
- for(j=0; j<lengths[i]; j++){
- glVertex2fv(vertices+k);
- k += 2;
- }
- glEnd();
- }
-}
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-/*we do not use the constans GL_... so that this file is independent of
- *<GL/gl.h>
- */
-
-#ifndef _PRIMITIVE_STREAM_H
-#define _PRIMITIVE_STREAM_H
-
-enum {PRIMITIVE_STREAM_FAN, PRIMITIVE_STREAM_STRIP};
-
-#include "definitions.h"
-
-class primStream {
- Int *lengths; /*length[i]=number of vertices of ith primitive*/
- Int *types; /*each primive has a type: FAN or STREAM*/
- Real *vertices; /*the size >= 2 * num_vertices, each vertex (u,v)*/
-
- /*the following size information are used for dynamic arrays*/
- Int index_lengths; /*the current available entry*/
- Int size_lengths; /*the allocated size of the array: lengths*/
- Int index_vertices;
- Int size_vertices;
-
- /*the vertex is inserted one by one. counter is used to
- *count the number of vertices which have been inserted so far in
- *the current primitive
- */
- Int counter;
-
-public:
- primStream(Int sizeLengths, Int sizeVertices);
- ~primStream();
-
- Int get_n_prims() //num of primitives
- {
- return index_lengths;
- }
- Int get_type(Int i) //the type of ith primitive
- {
- return types[i];
- }
- Int get_length(Int i) //the length of the ith primitive
- {
- return lengths[i];
- }
- Real* get_vertices() {return vertices;}
-
- /*the begining of inserting a new primitive.
- *reset counter to be 0.
- */
- void begin();
- void insert(Real u, Real v);
- void insert(Real v[2]) {insert(v[0], v[1]);}
- void end(Int type);
-
- Int num_triangles();
-
- void triangle(Real A[2], Real B[2], Real C[2])
- {
- begin();
- insert(A);
- insert(B);
- insert(C);
- end(PRIMITIVE_STREAM_FAN);
- }
- void print();
- void draw(); /*using GL to draw the primitives*/
-};
-
-
-
-
-
-
-
-
-#endif
-
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-
-
-static void swap(void *v[], int i, int j)
-{
- void *temp;
- temp = v[i];
- v[i] = v[j];
- v[j] = temp;
-}
-
-/*as an example to use this function to
- *sort integers, you need to supply the function
- *int comp(int *i1, int *i2)
- *{
- * if( *i1 < * i2) return -1;
- * else return 1;
- *}
- *and an array of pointers to integers:
- * int *v[100] (allocate space for where each v[i] points to).
- *then you can call:
- * quicksort( (void**)v, left, right, (int (*)(void *, void *))comp)
- */
-void quicksort(void *v[], int left, int right,
- int (*comp) (void *, void *))
-{
- int i, last;
- if(left >= right) /*do nothing if array contains */
- return; /*fewer than two elements*/
-
- swap(v, left, (left+right)/2);
- last = left;
- for(i=left+1; i<=right; i++)
- if((*comp)(v[i], v[left])<0)
- swap(v, ++last, i);
- swap(v, left, last);
- quicksort(v, left, last-1, comp);
- quicksort(v, last+1, right, comp);
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-#ifndef _QUICKSORT_H
-#define _QUICKSORT_H
-
-#include <stdlib.h>
-#include <stdio.h>
-
-void quicksort(void *v[], int left, int right,
- int (*comp) (void *, void *));
-
-#endif
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include "gluos.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include "glimports.h"
-#include "zlassert.h"
-#include <GL/gl.h>
-
-#include "rectBlock.h"
-
-rectBlock::rectBlock(gridBoundaryChain* left, gridBoundaryChain* right, Int beginVline, Int endVline)
-{
- Int i;
-
-
- upGridLineIndex = left->getVlineIndex(beginVline);
-
- lowGridLineIndex = left->getVlineIndex(endVline);
-
- Int n = upGridLineIndex-lowGridLineIndex+1; //number of grid lines
- leftIndices = (Int*) malloc(sizeof(Int) * n);
- assert(leftIndices);
- rightIndices = (Int*) malloc(sizeof(Int) * n);
- assert(rightIndices);
- for(i=0; i<n; i++)
- {
-
- leftIndices[i] = left->getInnerIndex(i+beginVline);
- rightIndices[i] = right->getInnerIndex(i+beginVline);
- }
-}
-
-
-rectBlock::~rectBlock()
-{
- free(leftIndices);
- free(rightIndices);
-}
-
-void rectBlock::print()
-{
- Int i;
- printf("block:\n");
- for(i=upGridLineIndex; i >= lowGridLineIndex; i--)
- {
- printf("gridline %i, (%i,%i)\n", i, leftIndices[upGridLineIndex-i], rightIndices[upGridLineIndex-i]);
- }
-}
-
-
-
-void rectBlock::draw(Real* u_values, Real* v_values)
-{
- Int i,j,k;
- //upgrid line to bot grid line
-#ifdef DEBUG
-printf("upGridLineIndex=%i, lowGridLineIndex=%i\n", upGridLineIndex, lowGridLineIndex);
-#endif
- for(k=0, i=upGridLineIndex; i > lowGridLineIndex; i--, k++)
- {
- glBegin(GL_QUAD_STRIP);
-
- for(j=leftIndices[k+1]; j<= rightIndices[k+1]; j++)
- {
- glVertex2f(u_values[j], v_values[i]);
- glVertex2f(u_values[j], v_values[i-1]);
- }
- glEnd();
- }
-}
-
-
-Int rectBlock::num_quads()
-{
- Int ret=0;
- Int k,i;
- for(k=0, i=upGridLineIndex; i>lowGridLineIndex; i--, k++)
- {
- ret += (rightIndices[k+1]-leftIndices[k+1]);
- }
- return ret;
-}
-
-Int rectBlockArray::num_quads()
-{
- Int ret=0;
- for(Int i=0; i<n_elements; i++)
- ret += array[i]->num_quads();
- return ret;
-}
-
-rectBlockArray::rectBlockArray(Int s)
-{
- Int i;
- n_elements = 0;
- size = s;
- array = (rectBlock**) malloc(sizeof(rectBlock*) * s);
- assert(array);
-//initialization
- for(i=0; i<s; i++)
- array[i] = NULL;
-}
-
-rectBlockArray::~rectBlockArray()
-{
- Int i;
- for(i=0; i<size; i++)
- {
- if(array[i] != NULL)
- delete array[i];
- }
- free(array);
-}
-
-//put to the end of the array, check the size
-void rectBlockArray::insert(rectBlock* newBlock)
-{
- Int i;
- if(n_elements == size) //full
- {
- rectBlock** temp = (rectBlock**) malloc(sizeof(rectBlock) * (2*size+1));
- assert(temp);
- //initialization
- for(i=0; i<2*size+1; i++)
- temp[i] = NULL;
-
- for(i=0; i<n_elements; i++)
- temp[i] = array[i];
-
- free(array);
- array = temp;
- size = 2*size + 1;
- }
-
- array[n_elements++] = newBlock;
-}
-
-void rectBlockArray::print()
-{
- Int i;
- for(i=0; i<n_elements; i++)
- array[i]->print();
-}
-
-void rectBlockArray::draw(Real* u_values, Real* v_values)
-{
- Int i;
- for(i=0; i<n_elements; i++)
- array[i]->draw(u_values, v_values);
-}
-
-
-
-
-
-
-
-
-
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-#ifndef _RECTBLOCK_H
-#define _RECTBLOCK_H
-
-#include "definitions.h"
-#include "gridWrap.h"
-
-class rectBlock{
- Int upGridLineIndex;
- Int lowGridLineIndex;
- Int* leftIndices; //up to bottome
- Int* rightIndices; //up to bottom
-public:
- //the arrays are copies.
- rectBlock(gridBoundaryChain* left, gridBoundaryChain* right, Int beginVline, Int endVline);
- ~rectBlock(); //free the two arrays
-
- Int get_upGridLineIndex() {return upGridLineIndex;}
- Int get_lowGridLineIndex() {return lowGridLineIndex;}
- Int* get_leftIndices() {return leftIndices;}
- Int* get_rightIndices() {return rightIndices;}
-
- Int num_quads();
-
- void print();
- void draw(Real* u_values, Real* v_values);
-};
-
-
-class rectBlockArray{
- rectBlock** array;
- Int n_elements;
- Int size;
-public:
- rectBlockArray(Int s);
- ~rectBlockArray();//delete avarything including the blocks
-
- Int get_n_elements() {return n_elements;}
- rectBlock* get_element(Int i) {return array[i];}
- void insert(rectBlock* newBlock); //only take the pointer, not ther cotent
-
- Int num_quads();
-
- void print();
- void draw(Real* u_values, Real* v_values);
-};
-
-
-
-#endif
-
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "glimports.h"
-#include "sampleComp.h"
-#include "sampleCompTop.h"
-#include "sampleCompBot.h"
-#include "sampleCompRight.h"
-
-
-
-#define max(a,b) ((a>b)? a:b)
-#define min(a,b) ((a>b)? b:a)
-
-void sampleConnectedComp(Real* topVertex, Real* botVertex,
- vertexArray* leftChain,
- Int leftStartIndex, Int leftEndIndex,
- vertexArray* rightChain,
- Int rightStartIndex, Int rightEndIndex,
- gridBoundaryChain* leftGridChain,
- gridBoundaryChain* rightGridChain,
- Int gridIndex1, Int gridIndex2,
- Int up_leftCornerWhere,
- Int up_leftCornerIndex,
- Int up_rightCornerWhere,
- Int up_rightCornerIndex,
- Int down_leftCornerWhere,
- Int down_leftCornerIndex,
- Int down_rightCornerWhere,
- Int down_rightCornerIndex,
- primStream* pStream,
- rectBlockArray* rbArray
- )
-{
-
- sampleCompLeft(topVertex, botVertex,
- leftChain,
- leftStartIndex, leftEndIndex,
- rightChain,
- rightStartIndex, rightEndIndex,
- leftGridChain,
- gridIndex1,
- gridIndex2,
- up_leftCornerWhere,
- up_leftCornerIndex,
- down_leftCornerWhere,
- down_leftCornerIndex,
- pStream);
-
-
- sampleCompRight(topVertex, botVertex,
- leftChain,
- leftStartIndex, leftEndIndex,
- rightChain,
- rightStartIndex,
- rightEndIndex,
- rightGridChain,
- gridIndex1, gridIndex2,
- up_rightCornerWhere,
- up_rightCornerIndex,
- down_rightCornerWhere,
- down_rightCornerIndex,
- pStream);
-
-
- sampleCompTop(topVertex,
- leftChain,
- leftStartIndex,
- rightChain,
- rightStartIndex,
- leftGridChain,
- rightGridChain,
- gridIndex1,
- up_leftCornerWhere,
- up_leftCornerIndex,
- up_rightCornerWhere,
- up_rightCornerIndex,
- pStream);
-
- sampleCompBot(botVertex,
- leftChain,
- leftEndIndex,
- rightChain,
- rightEndIndex,
- leftGridChain,
- rightGridChain,
- gridIndex2,
- down_leftCornerWhere,
- down_leftCornerIndex,
- down_rightCornerWhere,
- down_rightCornerIndex,
- pStream);
-
-
- //the center
-
- rbArray->insert(new rectBlock(leftGridChain, rightGridChain, gridIndex1, gridIndex2));
-
-
-}
-
-/*notice that we need rightChain because the
- *corners could be on the rightChain.
- *here comp means component.
- */
-void sampleCompLeft(Real* topVertex, Real* botVertex,
- vertexArray* leftChain,
- Int leftStartIndex, Int leftEndIndex,
- vertexArray* rightChain,
- Int rightStartIndex, Int rightEndIndex,
- gridBoundaryChain* leftGridChain,
- Int gridIndex1, Int gridIndex2,
- Int up_leftCornerWhere,
- Int up_leftCornerIndex,
- Int down_leftCornerWhere,
- Int down_leftCornerIndex,
- primStream* pStream)
-{
- /*find out whether there is a trim vertex which is
- *inbetween the top and bot grid lines or not.
- */
- Int midIndex1;
- Int midIndex2;
- Int gridMidIndex1 = 0, gridMidIndex2 = 0;
- //midIndex1: array[i] <= v, array[i-1] > v
- //midIndex2: array[i] >= v, array[i+1] < v
- // v(gridMidIndex1) >= v(midindex1) > v(gridMidIndex1+1)
- // v(gridMidIndex2-1) >= v(midIndex2) > v(gridMidIndex2) ??
- midIndex1 = leftChain->findIndexBelowGen(
- leftGridChain->get_v_value(gridIndex1),
- leftStartIndex,
- leftEndIndex);
-
- midIndex2 = -1; /*initilization*/
- if(midIndex1<= leftEndIndex && gridIndex1<gridIndex2)
- if(leftChain->getVertex(midIndex1)[1] >= leftGridChain->get_v_value(gridIndex2))
- {
- midIndex2 = leftChain->findIndexAboveGen(
- leftGridChain->get_v_value(gridIndex2),
- midIndex1, //midIndex1 <= midIndex2.
- leftEndIndex);
- gridMidIndex1 = leftGridChain->lookfor(leftChain->getVertex(midIndex1)[1],
- gridIndex1, gridIndex2);
- gridMidIndex2 = 1+leftGridChain->lookfor(leftChain->getVertex(midIndex2)[1],
- gridMidIndex1, gridIndex2);
- }
-
-
- /*to interprete the corner information*/
- Real* cornerTop;
- Real* cornerBot;
- Int cornerLeftStart;
- Int cornerLeftEnd;
- Int cornerRightUpEnd;
- Int cornerRightDownStart;
- if(up_leftCornerWhere == 0) /*left corner is on left chain*/
- {
- cornerTop = leftChain->getVertex(up_leftCornerIndex);
- cornerLeftStart = up_leftCornerIndex+1;
- cornerRightUpEnd = -1; /*no right*/
- }
- else if(up_leftCornerWhere == 1) /*left corner is on top*/
- {
- cornerTop = topVertex;
- cornerLeftStart = leftStartIndex;
- cornerRightUpEnd = -1; /*no right*/
- }
- else /*left corner is on right chain*/
- {
- cornerTop = topVertex;
- cornerLeftStart = leftStartIndex;
- cornerRightUpEnd = up_leftCornerIndex;
- }
-
- if(down_leftCornerWhere == 0) /*left corner is on left chain*/
- {
- cornerBot = leftChain->getVertex(down_leftCornerIndex);
- cornerLeftEnd = down_leftCornerIndex-1;
- cornerRightDownStart = rightEndIndex+1; /*no right*/
- }
- else if(down_leftCornerWhere == 1) /*left corner is on bot*/
- {
- cornerBot = botVertex;
- cornerLeftEnd = leftEndIndex;
- cornerRightDownStart = rightEndIndex+1; /*no right*/
- }
- else /*left corner is on the right chian*/
- {
- cornerBot = botVertex;
- cornerLeftEnd = leftEndIndex;
- cornerRightDownStart = down_leftCornerIndex;
- }
-
-
-
-
- /*sample*/
- if(midIndex2 >= 0) /*there is a trim point inbewteen grid lines*/
- {
-
- sampleLeftSingleTrimEdgeRegionGen(cornerTop, leftChain->getVertex(midIndex1),
- leftChain,
- cornerLeftStart,
- midIndex1-1,
- leftGridChain,
- gridIndex1,
- gridMidIndex1,
- rightChain,
- rightStartIndex,
- cornerRightUpEnd,
- 0, //no right down section
- -1,
- pStream);
-
- sampleLeftSingleTrimEdgeRegionGen(leftChain->getVertex(midIndex2),
- cornerBot,
- leftChain,
- midIndex2+1,
- cornerLeftEnd,
- leftGridChain,
- gridMidIndex2,
- gridIndex2,
- rightChain,
- 0, //no right up section
- -1,
- cornerRightDownStart,
- rightEndIndex,
- pStream);
-
-
- sampleLeftStripRecF(leftChain,
- midIndex1,
- midIndex2,
- leftGridChain,
- gridMidIndex1,
- gridMidIndex2,
- pStream);
- }
- else
- {
- sampleLeftSingleTrimEdgeRegionGen(cornerTop, cornerBot,
- leftChain,
- cornerLeftStart,
- cornerLeftEnd,
- leftGridChain,
- gridIndex1,
- gridIndex2,
- rightChain,
- rightStartIndex,
- cornerRightUpEnd,
- cornerRightDownStart,
- rightEndIndex,
- pStream);
- }
-}
-
-void sampleLeftSingleTrimEdgeRegionGen(Real topVert[2], Real botVert[2],
- vertexArray* leftChain,
- Int leftStart,
- Int leftEnd,
- gridBoundaryChain* gridChain,
- Int gridBeginIndex,
- Int gridEndIndex,
- vertexArray* rightChain,
- Int rightUpBegin,
- Int rightUpEnd,
- Int rightDownBegin,
- Int rightDownEnd,
- primStream* pStream)
-{
- Int i,j,k;
-
- /*creat an array to store all the up and down secments of the right chain,
- *and the left end grid points
- *
- *although vertex array is a dynamic array, but to gain efficiency,
- *it is better to initiliza the exact array size
- */
- vertexArray vArray(gridEndIndex-gridBeginIndex+1 +
- max(0,rightUpEnd - rightUpBegin+1)+
- max(0,rightDownEnd - rightDownBegin+1));
-
- /*append the vertices on the up section of thr right chain*/
- for(i=rightUpBegin; i<= rightUpEnd; i++)
- vArray.appendVertex(rightChain->getVertex(i));
-
- /*append the vertices of the left extremal grid points,
- *and at the same time, perform triangulation for the stair cases
- */
- vArray.appendVertex(gridChain->get_vertex(gridBeginIndex));
-
- for(k=1, i=gridBeginIndex+1; i<=gridEndIndex; i++, k++)
- {
- vArray.appendVertex(gridChain->get_vertex(i));
-
- /*output the fan of the grid points of the (i)th and (i-1)th grid line.
- */
- if(gridChain->getUlineIndex(i) < gridChain->getUlineIndex(i-1))
- {
- pStream->begin();
- pStream->insert(gridChain->get_vertex(i-1));
- for(j=gridChain->getUlineIndex(i); j<= gridChain->getUlineIndex(i-1); j++)
- pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i));
- pStream->end(PRIMITIVE_STREAM_FAN);
- }
- else if(gridChain->getUlineIndex(i) > gridChain->getUlineIndex(i-1))
- {
- pStream->begin();
- pStream->insert(gridChain->get_vertex(i));
- for(j=gridChain->getUlineIndex(i); j>= gridChain->getUlineIndex(i-1); j--)
- pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i-1));
- pStream->end(PRIMITIVE_STREAM_FAN);
- }
- /*otherwisem, the two are equal, so there is no fan to outout*/
- }
-
- /*then append all the vertices on the down section of the right chain*/
- for(i=rightDownBegin; i<= rightDownEnd; i++)
- vArray.appendVertex(rightChain->getVertex(i));
-
- monoTriangulationRecGen(topVert, botVert,
- leftChain, leftStart, leftEnd,
- &vArray, 0, vArray.getNumElements()-1,
- pStream);
-
-}
-
-
-
-
-
-
-
-
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-#ifndef _SAMPLECOMP_H
-#define _SAMPLECOMP_H
-
-#include "sampleMonoPoly.h"
-#include "rectBlock.h"
-
-void sampleConnectedComp(Real* topVertex, Real* botVertex,
- vertexArray* leftChain,
- Int leftStartIndex, Int botLeftIndex,
- vertexArray* rightChain,
- Int rightStartIndex, Int botRightIndex,
- gridBoundaryChain* leftGridChain,
- gridBoundaryChain* rightGridChain,
- Int gridIndex1, Int gridIndex2,
- Int up_leftCornerWhere,
- Int up_leftCornerIndex,
- Int up_rightCornerWhere,
- Int up_rightCornerIndex,
- Int down_leftCornerWhere,
- Int down_leftCornerIndex,
- Int down_rightCornerWhere,
- Int down_rightCornerIndex,
- primStream* pStream,
- rectBlockArray* rbArray
- );
-
-void sampleCompLeft(Real* topVertex, Real* botVertex,
- vertexArray* leftChain,
- Int leftStartIndex, Int leftEndIndex,
- vertexArray* rightChain,
- Int rightStartIndex, Int rightEndIndex,
- gridBoundaryChain* leftGridChain,
- Int gridIndex1, Int gridIndex2,
- Int up_leftCornerWhere,
- Int up_leftCornerIndex,
- Int down_leftCornerWhere,
- Int down_leftCornerIndex,
- primStream* pStream);
-
-void sampleLeftSingleTrimEdgeRegionGen(Real topVert[2], Real botVert[2],
- vertexArray* leftChain,
- Int leftStart,
- Int leftEnd,
- gridBoundaryChain* gridChain,
- Int gridBegindex,
- Int gridEndIndex,
- vertexArray* rightChain,
- Int rightUpBegin,
- Int rightUpEnd,
- Int rightDownBegin,
- Int rightDownEnd,
- primStream* pStream);
-
-#endif
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "zlassert.h"
-#include "sampleCompBot.h"
-#include "sampleCompRight.h"
-
-#define max(a,b) ((a>b)? a:b)
-
-//return: index_mono, index_pass
-//from [pass, mono] is strictly U-monotone
-//from [corner, pass] is <u
-// vertex[pass][0] >= u
-//if everybost is <u, then pass = end+1.
-//otherwise both mono and pass are meanng full and we have corner<=pass<=mono<=end
-void findBotLeftSegment(vertexArray* leftChain,
- Int leftEnd,
- Int leftCorner,
- Real u,
- Int& ret_index_mono,
- Int& ret_index_pass)
-{
- Int i;
-
- assert(leftCorner <= leftEnd);
- for(i=leftCorner; i<= leftEnd; i++)
- if(leftChain->getVertex(i)[0] >= u)
- break;
- ret_index_pass = i;
- if(ret_index_pass <= leftEnd)
- {
- for(i=ret_index_pass; i< leftEnd; i++)
- {
- if(leftChain->getVertex(i+1)[0] <= leftChain->getVertex(i)[0])
- break;
- }
- ret_index_mono = i;
- }
-
-}
-
-void findBotRightSegment(vertexArray* rightChain,
- Int rightEnd,
- Int rightCorner,
- Real u,
- Int& ret_index_mono,
- Int& ret_index_pass)
-{
- Int i;
- assert(rightCorner <= rightEnd);
- for(i=rightCorner; i<= rightEnd; i++)
- if(rightChain->getVertex(i)[0] <= u)
- break;
-
-
-
- ret_index_pass = i;
-
- if(ret_index_pass <= rightEnd)
- {
- for(i=ret_index_pass; i< rightEnd; i++)
- {
- if(rightChain->getVertex(i+1)[0] >= rightChain->getVertex(i)[0])
- break;
- }
- ret_index_mono = i;
- }
-}
-
-
-void sampleBotRightWithGridLinePost(Real* botVertex,
- vertexArray* rightChain,
- Int rightEnd,
- Int segIndexMono,
- Int segIndexPass,
- Int rightCorner,
- gridWrap* grid,
- Int gridV,
- Int leftU,
- Int rightU,
- primStream* pStream)
-{
- //the possible section which is to the right of rightU
- if(segIndexPass > rightCorner) //from corner to pass-1 is > u.
- {
- Real *tempBot;
- if(segIndexPass <= rightEnd) //there is a point to the left of u
- tempBot = rightChain->getVertex(segIndexPass);
- else //nothing is to the left of u.
- tempBot = botVertex;
- Real tempTop[2];
- tempTop[0] = grid->get_u_value(rightU);
- tempTop[1] = grid->get_v_value(gridV);
-
- monoTriangulation2(tempTop, tempBot,
- rightChain,
- rightCorner,
- segIndexPass-1,
- 0, // a decrease chain
- pStream);
- }
-
- //the possible section which is strictly Umonotone
- if(segIndexPass <= rightEnd) //segIndex pass and mono exist
- {
- //if there are grid points which are to the left of botVertex
- //then we should use botVertex to form a fan with these points to
- //optimize the triangulation
- int do_optimize = 1;
- if(botVertex[0] <= grid->get_u_value(leftU))
- do_optimize = 0;
- else
- {
- //we also have to make sure that botVertex is the left most vertex on the chain
- int i;
- for(i=segIndexMono; i<=rightEnd; i++)
- if(rightChain->getVertex(i)[0] <= botVertex[0])
- {
- do_optimize = 0;
- break;
- }
- }
-
- if(do_optimize)
- {
- //find midU so that grid->get_u_value(midU) <= botVertex[0]
- //and grid->get_u_value(midU) > botVertex[0]
- int midU = leftU;
- while(grid->get_u_value(midU) <= botVertex[0])
- {
- midU++;
- if(midU > rightU)
- break;
- }
- midU--;
-
- grid->outputFanWithPoint(gridV, leftU, midU, botVertex, pStream);
- stripOfFanRight(rightChain, segIndexMono, segIndexPass, grid, gridV, midU, rightU, pStream, 1);
- Real tempTop[2];
- tempTop[0] = grid->get_u_value(midU);
- tempTop[1] = grid->get_v_value(gridV);
- monoTriangulation2(tempTop, botVertex, rightChain, segIndexMono, rightEnd, 0, pStream);
- }
- else //not optimize
- {
- stripOfFanRight(rightChain, segIndexMono, segIndexPass, grid, gridV, leftU, rightU, pStream, 1);
- Real tempTop[2];
- tempTop[0] = grid->get_u_value(leftU);
- tempTop[1] = grid->get_v_value(gridV);
- monoTriangulation2(tempTop, botVertex, rightChain, segIndexMono, rightEnd, 0, pStream);
- }
- }
- else //the botVertex forms a fan witht eh grid points
- grid->outputFanWithPoint(gridV, leftU, rightU, botVertex, pStream);
-}
-
-void sampleBotRightWithGridLine(Real* botVertex,
- vertexArray* rightChain,
- Int rightEnd,
- Int rightCorner,
- gridWrap* grid,
- Int gridV,
- Int leftU,
- Int rightU,
- primStream* pStream)
-{
- //if right chaain is empty, then there is only one bot vertex with
- //one grid line
- if(rightEnd<rightCorner){
- grid->outputFanWithPoint(gridV, leftU, rightU, botVertex, pStream);
- return;
- }
-
- Int segIndexMono = 0, segIndexPass;
- findBotRightSegment(rightChain,
- rightEnd,
- rightCorner,
- grid->get_u_value(rightU),
- segIndexMono,
- segIndexPass);
-
- sampleBotRightWithGridLinePost(botVertex,
- rightChain,
- rightEnd,
- segIndexMono,
- segIndexPass,
- rightCorner,
- grid,
- gridV,
- leftU,
- rightU,
- pStream);
-}
-
-
-void sampleBotLeftWithGridLinePost(Real* botVertex,
- vertexArray* leftChain,
- Int leftEnd,
- Int segIndexMono,
- Int segIndexPass,
- Int leftCorner,
- gridWrap* grid,
- Int gridV,
- Int leftU,
- Int rightU,
- primStream* pStream)
-{
-
- //the possible section which is to the left of leftU
- if(segIndexPass > leftCorner) //at least leftCorner is to the left of leftU
- {
- Real *tempBot;
- if(segIndexPass <= leftEnd) //from corner to pass-1 is <u
- tempBot = leftChain->getVertex(segIndexPass);
- else //nothing is to the rigth of u
- tempBot = botVertex;
- Real tempTop[2];
- tempTop[0] = grid->get_u_value(leftU);
- tempTop[1] = grid->get_v_value(gridV);
- monoTriangulation2(tempTop, tempBot, leftChain, leftCorner, segIndexPass-1,
- 1, //a increase chain,
- pStream);
- }
- //the possible section which is strictly Umonotone
- if(segIndexPass <= leftEnd) //segIndexpass and mono exist
- {
- stripOfFanLeft(leftChain, segIndexMono, segIndexPass, grid, gridV, leftU, rightU, pStream, 1);
- Real tempTop[2];
- tempTop[0] = grid->get_u_value(rightU);
- tempTop[1] = grid->get_v_value(gridV);
-
- monoTriangulation2(tempTop, botVertex, leftChain, segIndexMono, leftEnd,
- 1, //increase chain
- pStream);
- }
- else //the botVertex forms a fan with the grid points
- {
- grid->outputFanWithPoint(gridV, leftU, rightU, botVertex, pStream);
- }
-
-}
-
-void sampleBotLeftWithGridLine(Real* botVertex,
- vertexArray* leftChain,
- Int leftEnd,
- Int leftCorner,
- gridWrap* grid,
- Int gridV,
- Int leftU,
- Int rightU,
- primStream* pStream)
-{
-
- //if leftChain is empty, then there is only one botVertex with one grid line
- if(leftEnd< leftCorner){
- grid->outputFanWithPoint(gridV, leftU, rightU, botVertex, pStream);
- return;
- }
-
- Int segIndexPass, segIndexMono = 0;
- findBotLeftSegment(leftChain, leftEnd, leftCorner, grid->get_u_value(leftU), segIndexMono, segIndexPass);
-
- sampleBotLeftWithGridLinePost(botVertex,
- leftChain,
- leftEnd,
- segIndexMono,
- segIndexPass,
- leftCorner,
- grid,
- gridV,
- leftU, rightU, pStream);
-}
-
-//return 1 if separator exists, 0 otherwise
-Int findBotSeparator(vertexArray* leftChain,
- Int leftEnd,
- Int leftCorner,
- vertexArray* rightChain,
- Int rightEnd,
- Int rightCorner,
- Int& ret_sep_left,
- Int& ret_sep_right)
-{
- Int oldLeftI, oldRightI, newLeftI, newRightI;
- Int i,j,k;
- Real leftMax /*= leftChain->getVertex(leftCorner)[0]*/;
- Real rightMin /*= rightChain->getVertex(rightCorner)[0]*/;
- if(leftChain->getVertex(leftCorner)[1] < rightChain->getVertex(rightCorner)[1])//leftlower
- {
- oldLeftI = leftCorner-1;
- oldRightI = rightCorner;
- leftMax = leftChain->getVertex(leftCorner)[0] - Real(1.0) ; //initilize to be left of leftCorner
- rightMin = rightChain->getVertex(rightCorner)[0];
- }
- else //rightlower
- {
- oldLeftI = leftCorner;
- oldRightI = rightCorner-1;
- leftMax = leftChain->getVertex(leftCorner)[0];
- rightMin = rightChain->getVertex(rightCorner)[0] + Real(1.0);
- }
-
- //i: the current working leftChain Index
- //j: the curent working right chian index
- //if(left(i) is lower than right(j), then the two chains above right(j) are separated.
- //else the two chains below left(i) are separated.
- i = leftCorner;
- j = rightCorner;
- while(1)
- {
- newLeftI = oldLeftI;
- newRightI = oldRightI;
- if(i> leftEnd) //left chain is doen , go through remaining right chain
- {
- for(k=j+1; k<= rightEnd; k++)
- {
- if(rightChain->getVertex(k)[0] > leftMax) //no conflict
- {
- //update oldRightI if necessary
- if(rightChain->getVertex(k)[0] < rightMin)
- {
- rightMin = rightChain->getVertex(k)[0];
- oldRightI = k;
- }
- }
- else //there is a conflict
- break; //the for-loop, above right(k+1) is separated: oldLeftI, oldRightI
- }
- break; //the while loop
- }
- else if(j > rightEnd) //right Chain is doen
- {
- for(k=i+1; k<= leftEnd; k++)
- {
- if(leftChain->getVertex(k)[0] < rightMin) //no conflict
- {
- //update oldLeftI if necessary
- if(leftChain->getVertex(k)[0] > leftMax)
- {
- leftMax = leftChain->getVertex(k)[0];
- oldLeftI = k;
- }
- }
- else //there is a conflict
- break; //the for-loop, above left(k+1) is separated: oldLeftI, oldRightI
- }
- break; //the while loop
- }
- else if(leftChain->getVertex(i)[1] < rightChain->getVertex(j)[1]) //left lower
- {
-
- if(leftChain->getVertex(i)[0] > leftMax) //update leftMax amd newLeftI
- {
- leftMax = leftChain->getVertex(i)[0];
- newLeftI = i;
- }
- for(k=j+1; k<= rightEnd; k++) //update rightMin and newRightI;
- {
- if(rightChain->getVertex(k)[1] < leftChain->getVertex(i)[1]) //right gets lower
- break;
- if(rightChain->getVertex(k)[0] < rightMin)
- {
- rightMin = rightChain->getVertex(k)[0];
- newRightI = k;
- }
- }
- j = k; //next working j, since j will he lower than i in next loop
- if(leftMax >= rightMin) //there is a conflict
- break;
- else //still no conflict
- {
- oldLeftI = newLeftI;
- oldRightI = newRightI;
-
- }
- }
- else //right lower
- {
- if(rightChain->getVertex(j)[0] < rightMin)
- {
- rightMin = rightChain->getVertex(j)[0];
- newRightI = j;
- }
- for(k=i+1; k<= leftEnd; k++)
- {
- if(leftChain->getVertex(k)[1] < rightChain->getVertex(j)[1])
- break;
- if(leftChain->getVertex(k)[0] > leftMax)
- {
- leftMax = leftChain->getVertex(k)[0];
- newLeftI = k;
- }
- }
- i=k; //nexct working i, since i will be lower than j next loop
- if(leftMax >= rightMin) //there is conflict
- break;
- else //still no conflict
- {
- oldLeftI = newLeftI;
- oldRightI = newRightI;
- }
- }
- }//end of while loop
- //now oldLeftI and oldRight I are the desired separator index notice that they are not
- //necessarily valid
- if(oldLeftI < leftCorner || oldRightI < rightCorner)
- return 0; //no separator
- else
- {
- ret_sep_left = oldLeftI;
- ret_sep_right = oldRightI;
- return 1;
- }
-}
-
-void sampleCompBot(Real* botVertex,
- vertexArray* leftChain,
- Int leftEnd,
- vertexArray* rightChain,
- Int rightEnd,
- gridBoundaryChain* leftGridChain,
- gridBoundaryChain* rightGridChain,
- Int gridIndex,
- Int down_leftCornerWhere,
- Int down_leftCornerIndex,
- Int down_rightCornerWhere,
- Int down_rightCornerIndex,
- primStream* pStream)
-{
-
- if(down_leftCornerWhere == 1 && down_rightCornerWhere == 1) //the bot is botVertex with possible grid points
- {
-
- leftGridChain->getGrid()->outputFanWithPoint(leftGridChain->getVlineIndex(gridIndex),
- leftGridChain->getUlineIndex(gridIndex),
- rightGridChain->getUlineIndex(gridIndex),
- botVertex,
- pStream);
- return;
- }
- else if(down_leftCornerWhere != 0)
- {
-
- Real* tempBot;
- Int tempRightEnd;
- if(down_leftCornerWhere == 1){
- tempRightEnd = rightEnd;
- tempBot = botVertex;
- }
- else
- {
- tempRightEnd = down_leftCornerIndex-1;
- tempBot = rightChain->getVertex(down_leftCornerIndex);
- }
-
- sampleBotRightWithGridLine(tempBot,
- rightChain,
- tempRightEnd,
- down_rightCornerIndex,
- rightGridChain->getGrid(),
- leftGridChain->getVlineIndex(gridIndex),
- leftGridChain->getUlineIndex(gridIndex),
- rightGridChain->getUlineIndex(gridIndex),
- pStream);
- }
- else if(down_rightCornerWhere != 2)
- {
-
- Real* tempBot;
- Int tempLeftEnd;
- if(down_rightCornerWhere == 1){
- tempLeftEnd = leftEnd;
- tempBot = botVertex;
- }
- else //right corner is on left chain
- {
- tempLeftEnd = down_rightCornerIndex-1;
- tempBot = leftChain->getVertex(down_rightCornerIndex);
- }
-
-
- sampleBotLeftWithGridLine(tempBot, leftChain, tempLeftEnd, down_leftCornerIndex,
- leftGridChain->getGrid(),
- leftGridChain->getVlineIndex(gridIndex),
- leftGridChain->getUlineIndex(gridIndex),
- rightGridChain->getUlineIndex(gridIndex),
- pStream);
-
- }
- else //down_leftCornereWhere == 0, down_rightCornerwhere == 2
- {
- sampleCompBotSimple(botVertex,
- leftChain,
- leftEnd,
- rightChain,
- rightEnd,
- leftGridChain,
- rightGridChain,
- gridIndex,
- down_leftCornerWhere,
- down_leftCornerIndex,
- down_rightCornerWhere,
- down_rightCornerIndex,
- pStream);
-
- return;
-
-#ifdef NOT_REACHABLE
- //the following code is trying to do some optimization, but not quite working. so it is not reachable, but leave it here for reference
- Int sep_left, sep_right;
- if(findBotSeparator(leftChain, leftEnd, down_leftCornerIndex,
- rightChain, rightEnd, down_rightCornerIndex,
- sep_left, sep_right)
- )//separator exiosts
- {
-
- if(leftChain->getVertex(sep_left)[0] >= leftGridChain->get_u_value(gridIndex) &&
- rightChain->getVertex(sep_right)[0] <= rightGridChain->get_u_value(gridIndex))
- {
- Int gridSep;
- Int segLeftMono, segLeftPass, segRightMono, segRightPass;
- findBotLeftSegment(leftChain,
- sep_left,
- down_leftCornerIndex,
- leftGridChain->get_u_value(gridIndex),
- segLeftMono,
- segLeftPass);
- findBotRightSegment(rightChain,
- sep_right,
- down_rightCornerIndex,
- rightGridChain->get_u_value(gridIndex),
- segRightMono,
- segRightPass);
- if(leftChain->getVertex(segLeftMono)[1] <= rightChain->getVertex(segRightMono)[1])
- {
- gridSep = rightGridChain->getUlineIndex(gridIndex);
- while(leftGridChain->getGrid()->get_u_value(gridSep) > leftChain->getVertex(segLeftMono)[0])
- gridSep--;
- }
- else
- {
- gridSep = leftGridChain->getUlineIndex(gridIndex);
- while(leftGridChain->getGrid()->get_u_value(gridSep) < rightChain->getVertex(segRightMono)[0])
- gridSep++;
- }
-
- sampleBotLeftWithGridLinePost(leftChain->getVertex(segLeftMono),
- leftChain,
- segLeftMono-1,
- segLeftMono-1,
- segLeftPass,
- down_leftCornerIndex,
- leftGridChain->getGrid(),
- leftGridChain->getVlineIndex(gridIndex),
- leftGridChain->getUlineIndex(gridIndex),
- gridSep,
- pStream);
- sampleBotRightWithGridLinePost(rightChain->getVertex(segRightMono),
- rightChain,
- segRightMono-1,
- segRightMono-1,
- segRightPass,
- down_rightCornerIndex,
- rightGridChain->getGrid(),
- rightGridChain->getVlineIndex(gridIndex),
- gridSep,
- rightGridChain->getUlineIndex(gridIndex),
- pStream);
- Real tempTop[2];
- tempTop[0] = leftGridChain->getGrid()->get_u_value(gridSep);
- tempTop[1] = leftGridChain->get_v_value(gridIndex);
- monoTriangulationRecGen(tempTop, botVertex,
- leftChain, segLeftMono, leftEnd,
- rightChain, segRightMono, rightEnd,
- pStream);
- }//end if both sides have vertices inside the gridboundary points
- else if(leftChain->getVertex(sep_left)[0] >= leftGridChain->get_u_value(gridIndex)) //left n right out
-
- {
- Int segLeftMono, segLeftPass;
- findBotLeftSegment(leftChain,
- sep_left,
- down_leftCornerIndex,
- leftGridChain->get_u_value(gridIndex),
- segLeftMono,
- segLeftPass);
- assert(segLeftPass <= sep_left); //make sure there is a point to the right of u.
- monoTriangulation2(leftGridChain->get_vertex(gridIndex),
- leftChain->getVertex(segLeftPass),
- leftChain,
- down_leftCornerIndex,
- segLeftPass-1,
- 1, //a increase chain
- pStream);
- stripOfFanLeft(leftChain, segLeftMono, segLeftPass,
- leftGridChain->getGrid(),
- leftGridChain->getVlineIndex(gridIndex),
- leftGridChain->getUlineIndex(gridIndex),
- rightGridChain->getUlineIndex(gridIndex),
- pStream,1 );
-/*
- sampleBotLeftWithGridLinePost(leftChain->getVertex(segLeftMono),
- leftChain,
- segLeftMono-1,
- segLeftMono-1,
- segLeftPass,
- down_leftCornerIndex,
- leftGridChain->getGrid(),
- leftGridChain->getVlineIndex(gridIndex),
- leftGridChain->getUlineIndex(gridIndex),
- rightGridChain->getUlineIndex(gridIndex),
- pStream);
-*/
-
- monoTriangulationRecGen(rightGridChain->get_vertex(gridIndex),
- botVertex,
- leftChain, segLeftMono, leftEnd,
- rightChain, down_rightCornerIndex, rightEnd,
- pStream);
- }//end left in right out
- else if(rightChain->getVertex(sep_right)[0] <= rightGridChain->get_u_value(gridIndex))//left out right in
- {
- Int segRightMono, segRightPass;
- findBotRightSegment(rightChain, sep_right, down_rightCornerIndex,
- rightGridChain->get_u_value(gridIndex),
- segRightMono,
- segRightPass);
-
- assert(segRightPass <= sep_right); //make sure there is a point to the left of u.
- monoTriangulation2(rightGridChain->get_vertex(gridIndex),
- rightChain->getVertex(segRightPass),
- rightChain,
- down_rightCornerIndex,
- segRightPass-1,
- 0, // a decrease chain
- pStream);
-
- stripOfFanRight(rightChain, segRightMono, segRightPass,
- rightGridChain->getGrid(),
- rightGridChain->getVlineIndex(gridIndex),
- leftGridChain->getUlineIndex(gridIndex),
- rightGridChain->getUlineIndex(gridIndex),
- pStream, 1);
-
-
- monoTriangulationRecGen(leftGridChain->get_vertex(gridIndex),
- botVertex,
- leftChain, down_leftCornerIndex, leftEnd,
- rightChain, segRightMono, rightEnd,
- pStream);
-
- }//end left out right in
- else //left out, right out
- {
- sampleCompBotSimple(botVertex,
- leftChain,
- leftEnd,
- rightChain,
- rightEnd,
- leftGridChain,
- rightGridChain,
- gridIndex,
- down_leftCornerWhere,
- down_leftCornerIndex,
- down_rightCornerWhere,
- down_rightCornerIndex,
- pStream);
-
- }//end leftout right out
- }//end if separator exists
- else //no separator
- {
-
- sampleCompBotSimple(botVertex,
- leftChain,
- leftEnd,
- rightChain,
- rightEnd,
- leftGridChain,
- rightGridChain,
- gridIndex,
- down_leftCornerWhere,
- down_leftCornerIndex,
- down_rightCornerWhere,
- down_rightCornerIndex,
- pStream);
- }
-#endif
- }//end id 0 2
-}//end if the functin
-
-
-void sampleCompBotSimple(Real* botVertex,
- vertexArray* leftChain,
- Int leftEnd,
- vertexArray* rightChain,
- Int rightEnd,
- gridBoundaryChain* leftGridChain,
- gridBoundaryChain* rightGridChain,
- Int gridIndex,
- Int down_leftCornerWhere,
- Int down_leftCornerIndex,
- Int down_rightCornerWhere,
- Int down_rightCornerIndex,
- primStream* pStream)
-{
- //the plan is to use monotriangulation algorithm.
- Int i,k;
- Real* ActualTop;
- Real* ActualBot;
- Int ActualLeftStart, ActualLeftEnd;
- Int ActualRightStart, ActualRightEnd;
-
- //creat an array to store the points on the grid line
- gridWrap* grid = leftGridChain->getGrid();
- Int gridV = leftGridChain->getVlineIndex(gridIndex);
- Int gridLeftU = leftGridChain->getUlineIndex(gridIndex);
- Int gridRightU = rightGridChain->getUlineIndex(gridIndex);
- Real2* gridPoints = (Real2*) malloc(sizeof(Real2) * (gridRightU - gridLeftU +1));
- assert(gridPoints);
-
- for(k=0, i=gridRightU; i>= gridLeftU; i--, k++)
- {
- gridPoints[k][0] = grid->get_u_value(i);
- gridPoints[k][1] = grid->get_v_value(gridV);
- }
-
- if(down_rightCornerWhere != 0) //rightCorner is not on lef
- ActualLeftEnd = leftEnd;
- else
- ActualLeftEnd = down_rightCornerIndex-1; //down_rightCornerIndex will be th actualBot
-
- if(down_leftCornerWhere != 0) //left corner is not on let chian
- ActualLeftStart = leftEnd+1; //meaning that there is no actual left section
- else
- ActualLeftStart = down_leftCornerIndex;
-
- vertexArray ActualLeftChain(max(0, ActualLeftEnd - ActualLeftStart +1) + gridRightU - gridLeftU +1);
-
- for(i=0; i<gridRightU - gridLeftU +1 ; i++)
- ActualLeftChain.appendVertex(gridPoints[i]);
- for(i=ActualLeftStart; i<= ActualLeftEnd; i++)
- ActualLeftChain.appendVertex(leftChain->getVertex(i));
-
- //determine ActualRightStart
- if(down_rightCornerWhere != 2) //right is not on right
- ActualRightStart = rightEnd +1; //meaning no section on right
- else
- ActualRightStart = down_rightCornerIndex;
-
- //determine actualrightEnd
- if(down_leftCornerWhere != 2) //left is not on right
- {
-
- ActualRightEnd = rightEnd;
- }
- else //left corner is on right
- {
- ActualRightEnd = down_leftCornerIndex-1; //down_leftCornerIndex will be the bot
-
- }
-
- //actual bot
- if(down_rightCornerWhere == 2)
- {
- if(down_leftCornerWhere == 2)
- ActualBot = rightChain->getVertex(down_leftCornerIndex);
- else
- ActualBot = botVertex;
- }
- else if(down_rightCornerWhere == 1) //right corner bot
- ActualBot = botVertex;
- else //down_rightCornerWhere == 0
- ActualBot = leftChain->getVertex(down_rightCornerIndex);
-
- ActualTop = gridPoints[0];
-/*
-printf("in bot simple, actual leftChain is \n");
-ActualLeftChain.print();
-printf("Actual Top = %f,%f\n", ActualTop[0],ActualTop[1]);
-printf("Actual Bot = %f,%f\n", ActualBot[0],ActualBot[1]);
-printf("Actual right start = %i, end=%i\n",ActualRightStart, ActualRightEnd);
-*/
- if(rightChain->getVertex(ActualRightStart)[1] == ActualTop[1])
- monoTriangulationRecGenOpt(rightChain->getVertex(ActualRightStart),
- ActualBot,
- &ActualLeftChain,
- 0,
- ActualLeftChain.getNumElements()-1,
- rightChain,
- ActualRightStart+1,
- ActualRightEnd,
- pStream);
- else
- monoTriangulationRecGenOpt(ActualTop, ActualBot,
- &ActualLeftChain,
- 1, //the first one is the top vertex
- ActualLeftChain.getNumElements()-1,
- rightChain,
- ActualRightStart,
- ActualRightEnd,
- pStream);
- free(gridPoints);
-}
-
-
-
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-#ifndef _SAMPLECOMPBOT_H
-#define _SAMPLECOMPBOT_H
-
-#include "sampleMonoPoly.h"
-
-void findBotLeftSegment(vertexArray* leftChain,
- Int leftEnd,
- Int leftCorner,
- Real u,
- Int& ret_index_mono,
- Int& ret_index_pass);
-
-void findBotRightSegment(vertexArray* rightChain,
- Int rightEnd,
- Int rightCorner,
- Real u,
- Int& ret_index_mono,
- Int& ret_index_pass);
-
-
-void sampleBotRightWithGridLinePost(Real* botVertex,
- vertexArray* rightChain,
- Int rightEnd,
- Int segIndexMono,
- Int segIndexPass,
- Int rightCorner,
- gridWrap* grid,
- Int gridV,
- Int leftU,
- Int rightU,
- primStream* pStream);
-
-
-void sampleBotRightWithGridLine(Real* botVertex,
- vertexArray* rightChain,
- Int rightEnd,
- Int rightCorner,
- gridWrap* grid,
- Int gridV,
- Int leftU,
- Int rightU,
- primStream* pStream);
-
-
-void sampleBotLeftWithGridLinePost(Real* botVertex,
- vertexArray* leftChain,
- Int leftEnd,
- Int segIndexMono,
- Int segIndexPass,
- Int leftCorner,
- gridWrap* grid,
- Int gridV,
- Int leftU,
- Int rightU,
- primStream* pStream);
-
-
-void sampleBotLeftWithGridLine(Real* botVertex,
- vertexArray* leftChain,
- Int leftEnd,
- Int leftCorner,
- gridWrap* grid,
- Int gridV,
- Int leftU,
- Int rightU,
- primStream* pStream);
-
-
-Int findBotSeparator(vertexArray* leftChain,
- Int leftEnd,
- Int leftCorner,
- vertexArray* rightChain,
- Int rightEnd,
- Int rightCorner,
- Int& ret_sep_left,
- Int& ret_sep_right);
-
-void sampleCompBot(Real* botVertex,
- vertexArray* leftChain,
- Int leftEnd,
- vertexArray* rightChain,
- Int rightEnd,
- gridBoundaryChain* leftGridChain,
- gridBoundaryChain* rightGridChain,
- Int gridIndex,
- Int down_leftCornerWhere,
- Int down_leftCornerIndex,
- Int down_rightCornerWhere,
- Int down_rightCornerIndex,
- primStream* pStream);
-
-void sampleCompBotSimple(Real* botVertex,
- vertexArray* leftChain,
- Int leftEnd,
- vertexArray* rightChain,
- Int rightEnd,
- gridBoundaryChain* leftGridChain,
- gridBoundaryChain* rightGridChain,
- Int gridIndex,
- Int down_leftCornerWhere,
- Int down_leftCornerIndex,
- Int down_rightCornerWhere,
- Int down_rightCornerIndex,
- primStream* pStream);
-
-#endif
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "gluos.h"
-#include "glimports.h"
-#include "zlassert.h"
-#include "sampleCompRight.h"
-
-#define max(a,b) ((a>b)? a:b)
-#define min(a,b) ((a>b)? b:a)
-
-
-
-#ifdef NOT_TAKEOUT
-
-/*notice that we need leftChain because the
- *corners could be on the leftChain.
- */
-void sampleCompRight(Real* topVertex, Real* botVertex,
- vertexArray* leftChain,
- Int leftStartIndex, Int leftEndIndex,
- vertexArray* rightChain,
- Int rightStartIndex, Int rightEndIndex,
- gridBoundaryChain* rightGridChain,
- Int gridIndex1, Int gridIndex2,
- Int up_rightCornerWhere,
- Int up_rightCornerIndex,
- Int down_rightCornerWhere,
- Int down_rightCornerIndex,
- primStream* pStream)
-{
- /*find out whether there is a trim vertex which is
- *inbetween the top and bot grid lines or not.
- */
- Int midIndex1;
- Int midIndex2;
- Int gridMidIndex1 = 0, gridMidIndex2 = 0;
- //midIndex1: array[i] <= v, array[i+1] > v
- //midIndex2: array[i] >= v, array[i+1] < v
- midIndex1 = rightChain->findIndexBelowGen(rightGridChain->get_v_value(gridIndex1),
- rightStartIndex,
- rightEndIndex);
- midIndex2 = -1; //initilization
- if(midIndex1 <= rightEndIndex && gridIndex1 < gridIndex2)
- if(rightChain->getVertex(midIndex1)[1] >= rightGridChain->get_v_value(gridIndex2))
- {
- //midIndex2 must exist:
- midIndex2 = rightChain->findIndexAboveGen(rightGridChain->get_v_value(gridIndex2),
- midIndex1, //midIndex1<=midIndex2
- rightEndIndex);
- //find gridMidIndex1 so that either it=gridIndex1 when the gridline is
- // at the same height as trim vertex midIndex1, or it is the last one
- //which is strictly above midIndex1.
- {
- Real temp = rightChain->getVertex(midIndex1)[1];
- if(rightGridChain->get_v_value(gridIndex1) == temp)
- gridMidIndex1 = gridIndex1;
- else
- {
- gridMidIndex1 = gridIndex1;
- while(rightGridChain->get_v_value(gridMidIndex1) > temp)
- gridMidIndex1++;
- gridMidIndex1--;
- }
- }//end of find gridMindIndex1
- //find gridMidIndex2 so that it is the (first one below or equal
- //midIndex) last one above or equal midIndex2
- {
- Real temp = rightChain->getVertex(midIndex2)[1];
- for(gridMidIndex2 = gridMidIndex1+1; gridMidIndex2 <= gridIndex2; gridMidIndex2++)
- if(rightGridChain->get_v_value(gridMidIndex2) <= temp)
- break;
-
- assert(gridMidIndex2 <= gridIndex2);
- }//end of find gridMidIndex2
- }
-
-
-
- //to interprete the corner information
- Real* cornerTop;
- Real* cornerBot;
- Int cornerRightStart;
- Int cornerRightEnd;
- Int cornerLeftUpEnd;
- Int cornerLeftDownStart;
- if(up_rightCornerWhere == 2) //right corner is on right chain
- {
- cornerTop = rightChain->getVertex(up_rightCornerIndex);
- cornerRightStart = up_rightCornerIndex+1;
- cornerLeftUpEnd = -1; //no left
- }
- else if(up_rightCornerWhere == 1) //right corner is on top
- {
- cornerTop = topVertex;
- cornerRightStart = rightStartIndex;
- cornerLeftUpEnd = -1; //no left
- }
- else //right corner is on left chain
- {
- cornerTop = topVertex;
- cornerRightStart = rightStartIndex;
- cornerLeftUpEnd = up_rightCornerIndex;
- }
-
- if(down_rightCornerWhere == 2) //right corner is on right chan
- {
- cornerBot = rightChain->getVertex(down_rightCornerIndex);
- cornerRightEnd = down_rightCornerIndex-1;
- cornerLeftDownStart = leftEndIndex+1; //no left
- }
- else if (down_rightCornerWhere == 1) //right corner is at bot
- {
- cornerBot = botVertex;
- cornerRightEnd = rightEndIndex;
- cornerLeftDownStart = leftEndIndex+1; //no left
- }
- else //right corner is on the left chain
- {
- cornerBot = botVertex;
- cornerRightEnd = rightEndIndex;
- cornerLeftDownStart = down_rightCornerIndex;
- }
-
- //sample
- if(midIndex2 >= 0) //there is a trm point between grid lines
- {
-
- sampleRightSingleTrimEdgeRegionGen(cornerTop, rightChain->getVertex(midIndex1),
- rightChain,
- cornerRightStart,
- midIndex1-1,
- rightGridChain,
- gridIndex1,
- gridMidIndex1,
- leftChain,
- leftStartIndex,
- cornerLeftUpEnd,
- 0, //no left down section,
- -1,
- pStream);
-
- sampleRightSingleTrimEdgeRegionGen(rightChain->getVertex(midIndex2),
- cornerBot,
- rightChain,
- midIndex2+1,
- cornerRightEnd,
- rightGridChain,
- gridMidIndex2,
- gridIndex2,
- leftChain,
- 0, //no left up section
- -1,
- cornerLeftDownStart,
- leftEndIndex,
- pStream);
-
- sampleRightStripRecF(rightChain,
- midIndex1,
- midIndex2,
- rightGridChain,
- gridMidIndex1,
- gridMidIndex2,
- pStream);
-
- }
- else
- {
- sampleRightSingleTrimEdgeRegionGen(cornerTop, cornerBot,
- rightChain,
- cornerRightStart,
- cornerRightEnd,
- rightGridChain,
- gridIndex1,
- gridIndex2,
- leftChain,
- leftStartIndex,
- cornerLeftUpEnd,
- cornerLeftDownStart,
- leftEndIndex,
- pStream);
- }
-}
-
-void sampleRightSingleTrimEdgeRegionGen(Real topVertex[2], Real botVertex[2],
- vertexArray* rightChain,
- Int rightStart,
- Int rightEnd,
- gridBoundaryChain* gridChain,
- Int gridBeginIndex,
- Int gridEndIndex,
- vertexArray* leftChain,
- Int leftUpBegin,
- Int leftUpEnd,
- Int leftDownBegin,
- Int leftDownEnd,
- primStream* pStream)
-{
- Int i,k;
- /*creat an array to store all the up and down secments of the left chain,
- *and the right end grid points
- *
- *although vertex array is a dynamic array, but to gain efficiency,
- *it is better to initiliza the exact array size
- */
- vertexArray vArray(gridEndIndex-gridBeginIndex+1 +
- max(0,leftUpEnd - leftUpBegin+1)+
- max(0,leftDownEnd - leftDownBegin+1));
- //append the vertices on the up section of the left chain
- for(i=leftUpBegin; i<= leftUpEnd; i++)
- vArray.appendVertex(leftChain->getVertex(i));
-
- //append the vertices of the right extremal grid points,
- //and at the same time, perform triangulation for the stair cases
- vArray.appendVertex(gridChain->get_vertex(gridBeginIndex));
-
- for(k=1, i=gridBeginIndex+1; i<= gridEndIndex; i++, k++)
- {
- vArray.appendVertex(gridChain->get_vertex(i));
-
- //output the fan of the grid points of the (i)th and (i-1)th grid line.
- gridChain->rightEndFan(i, pStream);
- }
-
- //append all the vertices on the down section of the left chain
- for(i=leftDownBegin; i<= leftDownEnd; i++)
- vArray.appendVertex(leftChain->getVertex(i));
- monoTriangulationRecGen(topVertex, botVertex,
- &vArray, 0, vArray.getNumElements()-1,
- rightChain, rightStart, rightEnd,
- pStream);
-}
-
-void sampleRightSingleTrimEdgeRegion(Real upperVert[2], Real lowerVert[2],
- gridBoundaryChain* gridChain,
- Int beginIndex,
- Int endIndex,
- primStream* pStream)
-{
- Int i,k;
- vertexArray vArray(endIndex-beginIndex+1);
- vArray.appendVertex(gridChain->get_vertex(beginIndex));
- for(k=1, i=beginIndex+1; i<= endIndex; i++, k++)
- {
- vArray.appendVertex(gridChain->get_vertex(i));
- //output the fan of the grid points of the (i)_th and i-1th gridLine
- gridChain->rightEndFan(i, pStream);
- }
- monoTriangulation2(upperVert, lowerVert, &vArray, 0, endIndex-beginIndex,
- 1, //increase chain (to the left)
- pStream);
-}
-
-
-/*the gridlines from rightGridChainStartIndex to
- *rightGridChainEndIndex are assumed to form a
- *connected componenet
- *the trm vertex of topRightIndex is assumed to be below
- *or equal the first gridLine, and the trm vertex of
- *botRightIndex is assumed to be above or equal the last gridline
- **there could be multipe trm vertices equal to the last gridline, but
- **only one could be equal to top gridline. shape: ____| (recall that
- **for left chain recF, we allow shape: |----
- *if botRightIndex<topRightIndex, then no connected componenet exists, and
- *no triangles are generated.
- *Othewise, botRightIndex>= topRightIndex, there is at least one triangles to
- *output
- */
-void sampleRightStripRecF(vertexArray* rightChain,
- Int topRightIndex,
- Int botRightIndex,
- gridBoundaryChain* rightGridChain,
- Int rightGridChainStartIndex,
- Int rightGridChainEndIndex,
- primStream* pStream
- )
-{
-
- //sstop conditionL: if topRightIndex > botRightIndex, then stop
- if(topRightIndex > botRightIndex)
- return;
-
- //if there is only one grid line, return
- if(rightGridChainStartIndex >= rightGridChainEndIndex)
- return;
-
-
- assert(rightChain->getVertex(topRightIndex)[1] <= rightGridChain->get_v_value(rightGridChainStartIndex) &&
- rightChain->getVertex(botRightIndex)[1] >= rightGridChain->get_v_value(rightGridChainEndIndex));
-
- //firstfind the first trim vertex which is strictly below the second top
- //grid line: index1.
- Real secondGridChainV = rightGridChain->get_v_value(rightGridChainStartIndex+1);
- Int index1 = topRightIndex;
- while(rightChain->getVertex(index1)[1] >= secondGridChainV){
- index1++;
- if(index1 > botRightIndex)
- break;
- }
- //now rightChain->getVertex(index1-1)[1] >= secondGridChainV and
- //rightChain->getVertex(index1)[1] < secondGridChainV and
- //we should include index1-1 to perform a gridStep
- index1--;
-
- //now we have rightChain->getVertex(index1)[1] >= secondGridChainV, and
- //rightChain->getVertex(index1+1)[1] < secondGridChainV
- sampleRightOneGridStep(rightChain, topRightIndex, index1, rightGridChain, rightGridChainStartIndex, pStream);
-
- //if rightChain->getVertex(index1)[1] ==secondGridChainV then we can
- //recurvesively to the rest
- if(rightChain->getVertex(index1)[1] == secondGridChainV)
- {
-
-
- sampleRightStripRecF(rightChain, index1, botRightIndex, rightGridChain, rightGridChainStartIndex+1, rightGridChainEndIndex, pStream);
- }
- else if(index1 < botRightIndex)
- {
- //otherwise, we have rightChain->getVertex(index1)[1] > secondV
- //let the next trim vertex be nextTrimVertex, (which should be strictly
- //below the second grid line). Find the last grid line index2 which is STRICTLY ABOVE
- //nextTrimVertex.
- //sample one trm edge region.
- Real *uppervert, *lowervert;
- uppervert = rightChain->getVertex(index1);
- lowervert = rightChain->getVertex(index1+1); //okay since index1<botRightindex
- Int index2 = rightGridChainStartIndex+1;
- while(rightGridChain->get_v_value(index2) > lowervert[1])
- {
- index2++;
- if(index2 > rightGridChainEndIndex)
- break;
- }
- index2--;
-
- sampleRightSingleTrimEdgeRegion(uppervert, lowervert, rightGridChain, rightGridChainStartIndex+1, index2, pStream);
-
- //recursion
- sampleRightStripRecF(rightChain, index1+1, botRightIndex, rightGridChain, index2, rightGridChainEndIndex, pStream);
- }
-}
-
-//the degenerate case of sampleRightOneGridStep
-void sampleRightOneGridStepNoMiddle(vertexArray* rightChain,
- Int beginRightIndex,
- Int endRightIndex,
- gridBoundaryChain* rightGridChain,
- Int rightGridChainStartIndex,
- primStream* pStream)
-{
- /*since there is no middle, there is at most one point which is on the
- *second grid line, there could be multiple points on the first (top)
- *grid line.
- */
- rightGridChain->rightEndFan(rightGridChainStartIndex+1, pStream);
- monoTriangulation2(rightGridChain->get_vertex(rightGridChainStartIndex),
- rightGridChain->get_vertex(rightGridChainStartIndex+1),
- rightChain,
- beginRightIndex,
- endRightIndex,
- 0, //decrease chain
- pStream);
-}
-
-//sampling the right area in between two grid lines
-//shape: _________|
-void sampleRightOneGridStep(vertexArray* rightChain,
- Int beginRightIndex,
- Int endRightIndex,
- gridBoundaryChain* rightGridChain,
- Int rightGridChainStartIndex,
- primStream* pStream)
-{
- if(checkMiddle(rightChain, beginRightIndex, endRightIndex,
- rightGridChain->get_v_value(rightGridChainStartIndex),
- rightGridChain->get_v_value(rightGridChainStartIndex+1))<0)
- {
- sampleRightOneGridStepNoMiddle(rightChain, beginRightIndex, endRightIndex, rightGridChain, rightGridChainStartIndex, pStream);
- return;
- }
-
- //copy into a polygn
- {
- directedLine* poly = NULL;
- sampledLine* sline;
- directedLine* dline;
- gridWrap* grid = rightGridChain->getGrid();
- float vert1[2];
- float vert2[2];
- Int i;
-
- Int innerInd = rightGridChain->getInnerIndex(rightGridChainStartIndex+1);
- Int upperInd = rightGridChain->getUlineIndex(rightGridChainStartIndex);
- Int lowerInd = rightGridChain->getUlineIndex(rightGridChainStartIndex+1);
- Real upperV = rightGridChain->get_v_value(rightGridChainStartIndex);
- Real lowerV = rightGridChain->get_v_value(rightGridChainStartIndex+1);
-
- //the upper gridline
- vert1[1]=vert2[1]=upperV;
- for(i=upperInd;
- i>innerInd;
- i--)
- {
- vert1[0]=grid->get_u_value(i);
- vert2[0]=grid->get_u_value(i-1);
- sline = new sampledLine(vert1, vert2);
- dline = new directedLine(INCREASING, sline);
- if(poly == NULL)
- poly = dline;
- else
- poly->insert(dline);
- }
-
- //the vertical grid line segment
- vert1[0]=vert2[0] = grid->get_u_value(innerInd);
- vert1[1]=upperV;
- vert2[1]=lowerV;
- sline=new sampledLine(vert1, vert2);
- dline=new directedLine(INCREASING, sline);
- if(poly == NULL)
- poly = dline;
- else
- poly->insert(dline);
-
- //the lower grid line
- vert1[1]=vert2[1]=lowerV;
- for(i=innerInd; i<lowerInd; i++)
- {
- vert1[0] = grid->get_u_value(i);
- vert2[0] = grid->get_u_value(i+1);
- sline = new sampledLine(vert1, vert2);
- dline = new directedLine(INCREASING, sline);
- poly->insert(dline);
- }
-
- //the edge connecting lower grid to right chain
- vert1[0]=grid->get_u_value(lowerInd);
- sline = new sampledLine(vert1, rightChain->getVertex(endRightIndex));
- dline = new directedLine(INCREASING, sline);
- poly->insert(dline);
-
-
- //the right Chain
- for(i=endRightIndex; i>beginRightIndex; i--)
- {
- sline = new sampledLine(rightChain->getVertex(i), rightChain->getVertex(i-1));
- dline = new directedLine(INCREASING, sline);
- poly->insert(dline);
- }
-
- //the edge connecting right chain with upper grid
- vert2[1]=upperV;
- vert2[0]=grid->get_u_value(upperInd);
- sline = new sampledLine(rightChain->getVertex(beginRightIndex), vert2);
- dline = new directedLine(INCREASING, sline);
- poly->insert(dline);
- monoTriangulationOpt(poly, pStream);
- //clean up
- poly->deleteSinglePolygonWithSline();
-
- return;
- }
-
- //this following code cannot be reached, but leave it for debuggig purpose.
- Int i;
- //find the maximal U-monotone chain of beginRightIndex, beginRightIndex+1,...
- i=beginRightIndex;
- Real prevU = rightChain->getVertex(i)[0];
- for(i=beginRightIndex+1; i<= endRightIndex; i++){
- Real thisU = rightChain->getVertex(i)[0];
- if(thisU < prevU)
- prevU = thisU;
- else
- break;
- }
- //from beginRightIndex to i-1 is strictly U-monotne
- //if(i-1==beginRightIndex and the vertex of rightchain is on the first
- //gridline, then we should use 2 vertices on the right chain. Of we only
- //use one (begin), we would output degenrate triangles.
- if(i-1 == beginRightIndex && rightChain->getVertex(beginRightIndex)[1] == rightGridChain->get_v_value(rightGridChainStartIndex))
- i++;
-
- Int j = endRightIndex -1;
- if(rightGridChain->getInnerIndex(rightGridChainStartIndex+1) < rightGridChain->getUlineIndex(rightGridChainStartIndex+1))
- {
- j = rightChain->findDecreaseChainFromEnd(i-1/*beginRightIndex*/, endRightIndex);
- Int temp = endRightIndex;
- //now from j+1 to end is strictly U-monotone.
- //if j+1 is on the last grid line, then we wat to skip to the vertex
- //whcih is strictly above the second grid line. This vertex must exist
- //since there is a middle vertex
- if(j+1 == endRightIndex)
- {
- while(rightChain->getVertex(j+1)[1] == rightGridChain->get_v_value(rightGridChainStartIndex+1))
- j--;
-
- monoTriangulation2(rightChain->getVertex(j+1),
- rightGridChain->get_vertex(rightGridChainStartIndex+1),
- rightChain,
- j+2,
- endRightIndex,
- 0, //a decrease chain
- pStream);
-
- temp = j+1;
- }
-
- stripOfFanRight(rightChain, temp, j+1, rightGridChain->getGrid(),
- rightGridChain->getVlineIndex(rightGridChainStartIndex+1),
- rightGridChain->getInnerIndex(rightGridChainStartIndex+1),
- rightGridChain->getUlineIndex(rightGridChainStartIndex+1),
- pStream,
- 0 //the grid line is below the trim line
- );
-
- }
-
-
- stripOfFanRight(rightChain, i-1, beginRightIndex, rightGridChain->getGrid(),
- rightGridChain->getVlineIndex(rightGridChainStartIndex),
- rightGridChain->getInnerIndex(rightGridChainStartIndex+1),
- rightGridChain->getUlineIndex(rightGridChainStartIndex),
- pStream,
- 1 //the grid line is above the trm lines
- );
-
- //monotone triangulate the remaining rightchain together with the
- //two vertices on the two grid v-lines
- Real vert[2][2];
- vert[0][0] = vert[1][0] = rightGridChain->getInner_u_value(rightGridChainStartIndex+1);
- vert[0][1] = rightGridChain->get_v_value(rightGridChainStartIndex);
- vert[1][1] = rightGridChain->get_v_value(rightGridChainStartIndex+1);
-
- monoTriangulation2(&vert[0][0],
- &vert[1][0],
- rightChain,
- i-1,
- j+1,
- 0, ///a decreae chain
- pStream);
-}
-
-#endif
-
-void stripOfFanRight(vertexArray* rightChain,
- Int largeIndex,
- Int smallIndex,
- gridWrap* grid,
- Int vlineIndex,
- Int ulineSmallIndex,
- Int ulineLargeIndex,
- primStream* pStream,
- Int gridLineUp /*1 if the grid line is above the trim lines*/
- )
-{
- assert(largeIndex >= smallIndex);
-
- Real grid_v_value;
- grid_v_value = grid->get_v_value(vlineIndex);
-
- Real2* trimVerts=(Real2*) malloc(sizeof(Real2)* (largeIndex-smallIndex+1));
- assert(trimVerts);
-
-
- Real2* gridVerts=(Real2*) malloc(sizeof(Real2)* (ulineLargeIndex-ulineSmallIndex+1));
- assert(gridVerts);
-
- Int k,i;
- if(! gridLineUp) /*trim line is above grid line, so trim vertices are going right when index increases*/
- for(k=0, i=smallIndex; i<=largeIndex; i++, k++)
- {
- trimVerts[k][0] = rightChain->getVertex(i)[0];
- trimVerts[k][1] = rightChain->getVertex(i)[1];
- }
- else
- for(k=0, i=largeIndex; i>=smallIndex; i--, k++)
- {
- trimVerts[k][0] = rightChain->getVertex(i)[0];
- trimVerts[k][1] = rightChain->getVertex(i)[1];
- }
-
- for(k=0, i=ulineSmallIndex; i<= ulineLargeIndex; i++, k++)
- {
- gridVerts[k][0] = grid->get_u_value(i);
- gridVerts[k][1] = grid_v_value;
- }
-
- if(gridLineUp)
- triangulateXYMono(
- ulineLargeIndex-ulineSmallIndex+1, gridVerts,
- largeIndex-smallIndex+1, trimVerts,
- pStream);
- else
- triangulateXYMono(largeIndex-smallIndex+1, trimVerts,
- ulineLargeIndex-ulineSmallIndex+1, gridVerts,
- pStream);
- free(trimVerts);
- free(gridVerts);
-}
-
-
-
-
-
-
-
-
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-#ifndef _SAMPLECOMPRIGHT_H
-#define _SAMPLECOMPRIGHT_H
-
-#define NOT_TAKEOUT
-
-#include "sampleMonoPoly.h"
-void stripOfFanRight(vertexArray* rightChain,
- Int largeIndex,
- Int smallIndex,
- gridWrap* grid,
- Int vlineIndex,
- Int ulineSmallIndex,
- Int ulineLargeIndex,
- primStream* pStream,
- Int gridLineUp /*1 if grid line is above the trim lines */
- );
-
-#ifdef NOT_TAKEOUT
-void sampleRightStripRecF(vertexArray* rightChain,
- Int topRightIndex,
- Int botRightIndex,
- gridBoundaryChain* rightGridChain,
- Int rightGridChainStartIndex,
- Int rightGridChainEndIndex,
- primStream* pStream
- );
-//the degenerate case of sampleRightOneGridStep
-void sampleRightOneGridStepNoMiddle(vertexArray* rightChain,
- Int beginRightIndex,
- Int endRightIndex,
- gridBoundaryChain* rightGridChain,
- Int rightGridChainStartIndex,
- primStream* pStream);
-//sampling the right area in between two grid lines
-//shape: _________|
-void sampleRightOneGridStep(vertexArray* rightChain,
- Int beginRightIndex,
- Int endRightIndex,
- gridBoundaryChain* rightGridChain,
- Int rightGridChainStartIndex,
- primStream* pStream);
-void sampleRightSingleTrimEdgeRegion(Real upperVert[2], Real lowerVert[2],
- gridBoundaryChain* gridChain,
- Int beginIndex,
- Int endIndex,
- primStream* pStream);
-//the degenerate case of sampleRightOneGridStep
-void sampleRightOneGridStepNoMiddle(vertexArray* rightChain,
- Int beginRightIndex,
- Int endRightIndex,
- gridBoundaryChain* rightGridChain,
- Int rightGridChainStartIndex,
- primStream* pStream);
-
-void sampleCompRight(Real* topVertex, Real* botVertex,
- vertexArray* leftChain,
- Int leftStartIndex, Int leftEndIndex,
- vertexArray* rightChain,
- Int rightStartIndex, Int rightEndIndex,
- gridBoundaryChain* rightGridChain,
- Int gridIndex1, Int gridIndex2,
- Int up_leftCornerWhere,
- Int up_leftCornerIndex,
- Int down_leftCornerWhere,
- Int down_leftCornerIndex,
- primStream* pStream);
-
-void sampleRightSingleTrimEdgeRegionGen(Real topVert[2], Real botVert[2],
- vertexArray* rightChain,
- Int rightStart,
- Int rightEnd,
- gridBoundaryChain* gridChain,
- Int gridBegindex,
- Int gridEndIndex,
- vertexArray* leftChain,
- Int leftUpBegin,
- Int leftUpEnd,
- Int leftDownBegin,
- Int leftDownEnd,
- primStream* pStream);
-#endif
-
-#endif
-
-
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-#include "zlassert.h"
-#include "sampleCompTop.h"
-#include "sampleCompRight.h"
-
-#define max(a,b) ((a>b)? a:b)
-
-//return : index_small, and index_large,
-//from [small, large] is strictly U-monotne,
-//from [large+1, end] is <u
-//and vertex[large][0] is >= u
-//if eveybody is <u, the large = start-1.
-//otherwise both large and small are meaningful and we have start<=small<=large<=end
-void findTopLeftSegment(vertexArray* leftChain,
- Int leftStart,
- Int leftEnd,
- Real u,
- Int& ret_index_small,
- Int& ret_index_large
- )
-{
- Int i;
- assert(leftStart <= leftEnd);
- for(i=leftEnd; i>= leftStart; i--)
- {
- if(leftChain->getVertex(i)[0] >= u)
- break;
- }
- ret_index_large = i;
- if(ret_index_large >= leftStart)
- {
- for(i=ret_index_large; i>leftStart; i--)
- {
- if(leftChain->getVertex(i-1)[0] <= leftChain->getVertex(i)[0])
- break;
- }
- ret_index_small = i;
- }
-}
-
-void findTopRightSegment(vertexArray* rightChain,
- Int rightStart,
- Int rightEnd,
- Real u,
- Int& ret_index_small,
- Int& ret_index_large)
-{
- Int i;
- assert(rightStart<=rightEnd);
- for(i=rightEnd; i>=rightStart; i--)
- {
- if(rightChain->getVertex(i)[0] <= u)
- break;
- }
- ret_index_large = i;
- if(ret_index_large >= rightStart)
- {
- for(i=ret_index_large; i>rightStart;i--)
- {
- if(rightChain->getVertex(i-1)[0] >= rightChain->getVertex(i)[0])
- break;
- }
- ret_index_small = i;
- }
-}
-
-
-void sampleTopRightWithGridLinePost(Real* topVertex,
- vertexArray* rightChain,
- Int rightStart,
- Int segIndexSmall,
- Int segIndexLarge,
- Int rightEnd,
- gridWrap* grid,
- Int gridV,
- Int leftU,
- Int rightU,
- primStream* pStream)
-{
- //the possible section which is to the right of rightU
- if(segIndexLarge < rightEnd)
- {
- Real *tempTop;
- if(segIndexLarge >= rightStart)
- tempTop = rightChain->getVertex(segIndexLarge);
- else
- tempTop = topVertex;
- Real tempBot[2];
- tempBot[0] = grid->get_u_value(rightU);
- tempBot[1] = grid->get_v_value(gridV);
-monoTriangulationRecGenOpt(tempTop, tempBot,
- NULL, 1,0,
- rightChain, segIndexLarge+1, rightEnd,
- pStream);
-/*
- monoTriangulation2(tempTop, tempBot,
- rightChain,
- segIndexLarge+1,
- rightEnd,
- 0, //a decrease chian
- pStream);
-*/
-
- }
-
- //the possible section which is strictly Umonotone
- if(segIndexLarge >= rightStart)
- {
- stripOfFanRight(rightChain, segIndexLarge, segIndexSmall, grid, gridV, leftU, rightU, pStream, 0);
- Real tempBot[2];
- tempBot[0] = grid->get_u_value(leftU);
- tempBot[1] = grid->get_v_value(gridV);
- monoTriangulation2(topVertex, tempBot, rightChain, rightStart, segIndexSmall, 0, pStream);
- }
- else //the topVertex forms a fan with the grid points
- grid->outputFanWithPoint(gridV, leftU, rightU, topVertex, pStream);
-}
-
-void sampleTopRightWithGridLine(Real* topVertex,
- vertexArray* rightChain,
- Int rightStart,
- Int rightEnd,
- gridWrap* grid,
- Int gridV,
- Int leftU,
- Int rightU,
- primStream* pStream
- )
-{
- //if right chian is empty, then there is only one topVertex with one grid line
- if(rightEnd < rightStart){
- grid->outputFanWithPoint(gridV, leftU, rightU, topVertex, pStream);
- return;
- }
-
- Int segIndexSmall = 0, segIndexLarge;
- findTopRightSegment(rightChain,
- rightStart,
- rightEnd,
- grid->get_u_value(rightU),
- segIndexSmall,
- segIndexLarge
- );
- sampleTopRightWithGridLinePost(topVertex, rightChain,
- rightStart,
- segIndexSmall,
- segIndexLarge,
- rightEnd,
- grid,
- gridV,
- leftU,
- rightU,
- pStream);
-}
-
-
-void sampleTopLeftWithGridLinePost(Real* topVertex,
- vertexArray* leftChain,
- Int leftStart,
- Int segIndexSmall,
- Int segIndexLarge,
- Int leftEnd,
- gridWrap* grid,
- Int gridV,
- Int leftU,
- Int rightU,
- primStream* pStream)
-{
- //the possible section which is to the left of leftU
-
- if(segIndexLarge < leftEnd)
- {
- Real *tempTop;
- if(segIndexLarge >= leftStart)
- tempTop = leftChain->getVertex(segIndexLarge);
- else
- tempTop = topVertex;
- Real tempBot[2];
- tempBot[0] = grid->get_u_value(leftU);
- tempBot[1] = grid->get_v_value(gridV);
-
- monoTriangulation2(tempTop, tempBot,
- leftChain,
- segIndexLarge+1,
- leftEnd,
- 1, //a increase chian
- pStream);
- }
-
- //the possible section which is strictly Umonotone
- if(segIndexLarge >= leftStart)
- {
- //if there are grid points which are to the right of topV,
- //then we should use topVertex to form a fan with these points to
- //optimize the triangualtion
- int do_optimize=1;
- if(topVertex[0] >= grid->get_u_value(rightU))
- do_optimize = 0;
- else
- {
- //we also have to make sure that topVertex are the right most vertex
- //on the chain.
- int i;
- for(i=leftStart; i<=segIndexSmall; i++)
- if(leftChain->getVertex(i)[0] >= topVertex[0])
- {
- do_optimize = 0;
- break;
- }
- }
-
- if(do_optimize)
- {
- //find midU so that grid->get_u_value(midU) >= topVertex[0]
- //and grid->get_u_value(midU-1) < topVertex[0]
- int midU=rightU;
- while(grid->get_u_value(midU) >= topVertex[0])
- {
- midU--;
- if(midU < leftU)
- break;
- }
- midU++;
-
- grid->outputFanWithPoint(gridV, midU, rightU, topVertex, pStream);
- stripOfFanLeft(leftChain, segIndexLarge, segIndexSmall, grid, gridV, leftU, midU, pStream, 0);
- Real tempBot[2];
- tempBot[0] = grid->get_u_value(midU);
- tempBot[1] = grid->get_v_value(gridV);
- monoTriangulation2(topVertex, tempBot, leftChain, leftStart, segIndexSmall, 1, pStream);
- }
- else //not optimize
- {
-
- stripOfFanLeft(leftChain, segIndexLarge, segIndexSmall, grid, gridV, leftU, rightU, pStream, 0);
- Real tempBot[2];
- tempBot[0] = grid->get_u_value(rightU);
- tempBot[1] = grid->get_v_value(gridV);
- monoTriangulation2(topVertex, tempBot, leftChain, leftStart, segIndexSmall, 1, pStream);
- }
- }
- else //the topVertex forms a fan with the grid points
- grid->outputFanWithPoint(gridV, leftU, rightU, topVertex, pStream);
-}
-
-
-void sampleTopLeftWithGridLine(Real* topVertex,
- vertexArray* leftChain,
- Int leftStart,
- Int leftEnd,
- gridWrap* grid,
- Int gridV,
- Int leftU,
- Int rightU,
- primStream* pStream
- )
-{
- Int segIndexSmall = 0, segIndexLarge;
- //if left chain is empty, then there is only one top vertex with one grid
- // line
- if(leftEnd < leftStart) {
- grid->outputFanWithPoint(gridV, leftU, rightU, topVertex, pStream);
- return;
- }
- findTopLeftSegment(leftChain,
- leftStart,
- leftEnd,
- grid->get_u_value(leftU),
- segIndexSmall,
- segIndexLarge
- );
- sampleTopLeftWithGridLinePost(topVertex,
- leftChain,
- leftStart,
- segIndexSmall,
- segIndexLarge,
- leftEnd,
- grid,
- gridV,
- leftU,
- rightU,
- pStream);
-}
-
-
-//return 1 if saprator exits, 0 otherwise
-Int findTopSeparator(vertexArray* leftChain,
- Int leftStartIndex,
- Int leftEndIndex,
- vertexArray* rightChain,
- Int rightStartIndex,
- Int rightEndIndex,
- Int& ret_sep_left,
- Int& ret_sep_right)
-{
-
- Int oldLeftI, oldRightI, newLeftI, newRightI;
- Int i,j,k;
- Real leftMax /*= leftChain->getVertex(leftEndIndex)[0]*/;
- Real rightMin /*= rightChain->getVertex(rightEndIndex)[0]*/;
- if(leftChain->getVertex(leftEndIndex)[1] > rightChain->getVertex(rightEndIndex)[1]) //left higher
- {
- oldLeftI = leftEndIndex+1;
- oldRightI = rightEndIndex;
- leftMax = leftChain->getVertex(leftEndIndex)[0] - Real(1.0); //initilza to left of leftU
- rightMin = rightChain->getVertex(rightEndIndex)[0];
- }
- else
- {
- oldLeftI = leftEndIndex;
- oldRightI = rightEndIndex+1;
- leftMax = leftChain->getVertex(leftEndIndex)[0];
- rightMin = rightChain->getVertex(rightEndIndex)[0] + Real(1.0);
- }
-
- //i: the current working leftChain index,
- //j: the current working rightChain index,
- //if left(i) is higher than right(j), then the two chains beloew right(j) are separated.
- //else the two chains below left(i) are separeated.
- i=leftEndIndex;
- j=rightEndIndex;
- while(1)
- {
- newLeftI = oldLeftI;
- newRightI = oldRightI;
-
- if(i<leftStartIndex) //left chain is done, go through remining right chain.
- {
- for(k=j-1; k>= rightStartIndex; k--)
- {
- if(rightChain->getVertex(k)[0] > leftMax) //no conflict
- {
- //update oldRightI if necessary
- if(rightChain->getVertex(k)[0] < rightMin)
- {
- rightMin = rightChain->getVertex(k)[0];
- oldRightI = k;
- }
- }
- else //there is a conflict
- break; //the for-loop. below right(k-1) is seperated: oldLeftI, oldRightI.
- }
- break; //the while loop
- }
- else if(j<rightStartIndex) //rightChain is done
- {
- for(k=i-1; k>= leftStartIndex; k--)
- {
- if(leftChain->getVertex(k)[0] < rightMin) //no conflict
- {
- //update oldLeftI if necessary
- if(leftChain->getVertex(k)[0] > leftMax)
- {
- leftMax = leftChain->getVertex(k)[0];
- oldLeftI = k;
- }
- }
- else //there is a conflict
- break; //the for loop
- }
- break; //the while loop
- }
- else if(leftChain->getVertex(i)[1] > rightChain->getVertex(j)[1]) //left hgiher
- {
- if(leftChain->getVertex(i)[0] > leftMax) //update leftMax and newLeftI.
- {
- leftMax = leftChain->getVertex(i)[0];
- newLeftI = i;
- }
- for(k=j-1; k>= rightStartIndex; k--) //update rightMin and newRightI.
- {
- if(rightChain->getVertex(k)[1] > leftChain->getVertex(i)[1])
- break;
- if(rightChain->getVertex(k)[0] < rightMin)
- {
- rightMin = rightChain->getVertex(k)[0];
- newRightI = k;
- }
- }
- j = k; //next working j, since j will be higher than i in next loop
- if(leftMax >= rightMin) //there is a conflict
- break;
- else //still no conflict
- {
- oldLeftI = newLeftI;
- oldRightI = newRightI;
- }
- }
- else //right higher
- {
- if(rightChain->getVertex(j)[0] < rightMin)
- {
- rightMin = rightChain->getVertex(j)[0];
- newRightI = j;
- }
- for(k=i-1; k>= leftStartIndex; k--)
- {
- if(leftChain->getVertex(k)[1] > rightChain->getVertex(j)[1])
- break;
- if(leftChain->getVertex(k)[0] > leftMax)
- {
- leftMax = leftChain->getVertex(k)[0];
- newLeftI = k;
- }
- }
- i = k; //next working i, since i will be higher than j next loop
-
- if(leftMax >= rightMin) //there is a conflict
- break;
- else //still no conflict
- {
- oldLeftI = newLeftI;
- oldRightI = newRightI;
- }
- }
- }//end of while loop
- //now oldLeftI and oldRightI are the desired separeator index, notice that there are not necessarily valid
- if(oldLeftI > leftEndIndex || oldRightI > rightEndIndex)
- return 0;
- else
- {
- ret_sep_left = oldLeftI;
- ret_sep_right = oldRightI;
- return 1;
- }
-}
-
-
-void sampleCompTop(Real* topVertex,
- vertexArray* leftChain,
- Int leftStartIndex,
- vertexArray* rightChain,
- Int rightStartIndex,
- gridBoundaryChain* leftGridChain,
- gridBoundaryChain* rightGridChain,
- Int gridIndex1,
- Int up_leftCornerWhere,
- Int up_leftCornerIndex,
- Int up_rightCornerWhere,
- Int up_rightCornerIndex,
- primStream* pStream)
-{
- if(up_leftCornerWhere == 1 && up_rightCornerWhere == 1) //the top is topVertex with possible grid points
- {
- leftGridChain->getGrid()->outputFanWithPoint(leftGridChain->getVlineIndex(gridIndex1),
- leftGridChain->getUlineIndex(gridIndex1),
- rightGridChain->getUlineIndex(gridIndex1),
- topVertex,
- pStream);
- return;
- }
-
- else if(up_leftCornerWhere != 0)
- {
- Real* tempTop;
- Int tempRightStart;
- if(up_leftCornerWhere == 1){
- tempRightStart = rightStartIndex;
- tempTop = topVertex;
- }
- else
- {
- tempRightStart = up_leftCornerIndex+1;
- tempTop = rightChain->getVertex(up_leftCornerIndex);
- }
- sampleTopRightWithGridLine(tempTop, rightChain, tempRightStart, up_rightCornerIndex,
- rightGridChain->getGrid(),
- leftGridChain->getVlineIndex(gridIndex1),
- leftGridChain->getUlineIndex(gridIndex1),
- rightGridChain->getUlineIndex(gridIndex1),
- pStream);
- }
- else if(up_rightCornerWhere != 2)
- {
- Real* tempTop;
- Int tempLeftStart;
- if(up_rightCornerWhere == 1)
- {
- tempLeftStart = leftStartIndex;
- tempTop = topVertex;
- }
- else //0
- {
- tempLeftStart = up_rightCornerIndex+1;
- tempTop = leftChain->getVertex(up_rightCornerIndex);
- }
-/*
- sampleTopLeftWithGridLine(tempTop, leftChain, tempLeftStart, up_leftCornerIndex,
- leftGridChain->getGrid(),
- leftGridChain->getVlineIndex(gridIndex1),
- leftGridChain->getUlineIndex(gridIndex1),
- rightGridChain->getUlineIndex(gridIndex1),
- pStream);
-*/
- sampleCompTopSimple(topVertex,
- leftChain,
- leftStartIndex,
- rightChain,
- rightStartIndex,
- leftGridChain,
- rightGridChain,
- gridIndex1,
- up_leftCornerWhere,
- up_leftCornerIndex,
- up_rightCornerWhere,
- up_rightCornerIndex,
- pStream);
- }
- else //up_leftCornerWhere == 0, up_rightCornerWhere == 2.
- {
- sampleCompTopSimple(topVertex,
- leftChain,
- leftStartIndex,
- rightChain,
- rightStartIndex,
- leftGridChain,
- rightGridChain,
- gridIndex1,
- up_leftCornerWhere,
- up_leftCornerIndex,
- up_rightCornerWhere,
- up_rightCornerIndex,
- pStream);
- return;
-#ifdef NOT_REACHABLE //code is not reachable, for test purpose only
- //the following code is trying to do some optimization, but not quite working, also see sampleCompBot.C:
- Int sep_left, sep_right;
- if(findTopSeparator(leftChain,
- leftStartIndex,
- up_leftCornerIndex,
- rightChain,
- rightStartIndex,
- up_rightCornerIndex,
- sep_left,
- sep_right)
- ) //separator exists
- {
-
- if( leftChain->getVertex(sep_left)[0] >= leftGridChain->get_u_value(gridIndex1) &&
- rightChain->getVertex(sep_right)[0] <= rightGridChain->get_u_value(gridIndex1))
- {
- Int gridSep;
- Int segLeftSmall, segLeftLarge, segRightSmall, segRightLarge;
- Int valid=1; //whether the gridStep is valid or not.
- findTopLeftSegment(leftChain,
- sep_left,
- up_leftCornerIndex,
- leftGridChain->get_u_value(gridIndex1),
- segLeftSmall,
- segLeftLarge);
- findTopRightSegment(rightChain,
- sep_right,
- up_rightCornerIndex,
- rightGridChain->get_u_value(gridIndex1),
- segRightSmall,
- segRightLarge);
- if(leftChain->getVertex(segLeftSmall)[1] >= rightChain->getVertex(segRightSmall)[1])
- {
- gridSep = rightGridChain->getUlineIndex(gridIndex1);
- while(leftGridChain->getGrid()->get_u_value(gridSep) > leftChain->getVertex(segLeftSmall)[0])
- gridSep--;
- if(segLeftSmall<segLeftLarge)
- if(leftGridChain->getGrid()->get_u_value(gridSep) < leftChain->getVertex(segLeftSmall+1)[0])
- {
- valid = 0;
- }
- }
- else
- {
- gridSep = leftGridChain->getUlineIndex(gridIndex1);
- while(leftGridChain->getGrid()->get_u_value(gridSep) < rightChain->getVertex(segRightSmall)[0])
- gridSep++;
- if(segRightSmall<segRightLarge)
- if(leftGridChain->getGrid()->get_u_value(gridSep) > rightChain->getVertex(segRightSmall+1)[0])
- {
- valid = 0;
- }
- }
-
- if(! valid)
- {
- sampleCompTopSimple(topVertex,
- leftChain,
- leftStartIndex,
- rightChain,
- rightStartIndex,
- leftGridChain,
- rightGridChain,
- gridIndex1,
- up_leftCornerWhere,
- up_leftCornerIndex,
- up_rightCornerWhere,
- up_rightCornerIndex,
- pStream);
- }
- else
- {
- sampleTopLeftWithGridLinePost(leftChain->getVertex(segLeftSmall),
- leftChain,
- segLeftSmall+1,
- segLeftSmall+1,
- segLeftLarge,
- up_leftCornerIndex,
- leftGridChain->getGrid(),
- leftGridChain->getVlineIndex(gridIndex1),
- leftGridChain->getUlineIndex(gridIndex1),
- gridSep,
- pStream);
- sampleTopRightWithGridLinePost(rightChain->getVertex(segRightSmall),
- rightChain,
- segRightSmall+1,
- segRightSmall+1,
- segRightLarge,
- up_rightCornerIndex,
- leftGridChain->getGrid(),
- leftGridChain->getVlineIndex(gridIndex1),
- gridSep,
- rightGridChain->getUlineIndex(gridIndex1),
- pStream);
- Real tempBot[2];
- tempBot[0] = leftGridChain->getGrid()->get_u_value(gridSep);
- tempBot[1] = leftGridChain->get_v_value(gridIndex1);
- monoTriangulationRecGen(topVertex, tempBot,
- leftChain, leftStartIndex, segLeftSmall,
- rightChain, rightStartIndex, segRightSmall,
- pStream);
- }
- }//end if both sides have vetices inside the gridboundary points
- else if(leftChain->getVertex(sep_left)[0] >= leftGridChain->get_u_value(gridIndex1)) //left is in, right is nout
- {
-
- Int segLeftSmall, segLeftLarge;
- findTopLeftSegment(leftChain,
- sep_left,
- up_leftCornerIndex,
- leftGridChain->get_u_value(gridIndex1),
- segLeftSmall,
- segLeftLarge);
- assert(segLeftLarge >= sep_left);
- monoTriangulation2(leftChain->getVertex(segLeftLarge),
- leftGridChain->get_vertex(gridIndex1),
- leftChain,
- segLeftLarge+1,
- up_leftCornerIndex,
- 1, //a increase chain,
- pStream);
-
- stripOfFanLeft(leftChain, segLeftLarge, segLeftSmall,
- leftGridChain->getGrid(),
- leftGridChain->getVlineIndex(gridIndex1),
- leftGridChain->getUlineIndex(gridIndex1),
- rightGridChain->getUlineIndex(gridIndex1),
- pStream, 0);
-
-
- monoTriangulationRecGen(topVertex, rightGridChain->get_vertex(gridIndex1),
- leftChain, leftStartIndex, segLeftSmall,
- rightChain, rightStartIndex, up_rightCornerIndex,
- pStream);
- }//end left in right out
- else if(rightChain->getVertex(sep_right)[0] <= rightGridChain->get_u_value(gridIndex1))
- {
- Int segRightSmall, segRightLarge;
- findTopRightSegment(rightChain,
- sep_right,
- up_rightCornerIndex,
- rightGridChain->get_u_value(gridIndex1),
- segRightSmall,
- segRightLarge);
- assert(segRightLarge>=sep_right);
- monoTriangulation2(rightChain->getVertex(segRightLarge),
- rightGridChain->get_vertex(gridIndex1),
- rightChain,
- segRightLarge+1,
- up_rightCornerIndex,
- 0, //a decrease chain
- pStream);
- stripOfFanRight(rightChain, segRightLarge, segRightSmall,
- rightGridChain->getGrid(),
- rightGridChain->getVlineIndex(gridIndex1),
- leftGridChain->getUlineIndex(gridIndex1),
- rightGridChain->getUlineIndex(gridIndex1),
- pStream, 0);
-
-
- monoTriangulationRecGen(topVertex, leftGridChain->get_vertex(gridIndex1),
- leftChain, leftStartIndex, up_leftCornerIndex,
- rightChain, rightStartIndex,segRightSmall,
- pStream);
-
- }//end left out rigth in
- else //left out , right out
- {
-
- sampleCompTopSimple(topVertex,
- leftChain,
- leftStartIndex,
- rightChain,
- rightStartIndex,
- leftGridChain,
- rightGridChain,
- gridIndex1,
- up_leftCornerWhere,
- up_leftCornerIndex,
- up_rightCornerWhere,
- up_rightCornerIndex,
- pStream);
- }//end leftout, right out
- }//end if separator exixts.
- else //no separator
- {
-
- sampleCompTopSimple(topVertex,
- leftChain,
- leftStartIndex,
- rightChain,
- rightStartIndex,
- leftGridChain,
- rightGridChain,
- gridIndex1,
- up_leftCornerWhere,
- up_leftCornerIndex,
- up_rightCornerWhere,
- up_rightCornerIndex,
- pStream);
- }
-#endif
- }//end if 0,2
-}//end if the function
-
-
-static void sampleCompTopSimpleOpt(gridWrap* grid,
- Int gridV,
- Real* topVertex, Real* botVertex,
- vertexArray* inc_chain, Int inc_current, Int inc_end,
- vertexArray* dec_chain, Int dec_current, Int dec_end,
- primStream* pStream)
-{
- if(gridV <= 0 || dec_end<dec_current || inc_end <inc_current)
- {
- monoTriangulationRecGenOpt(topVertex, botVertex,
- inc_chain, inc_current, inc_end,
- dec_chain, dec_current, dec_end,
- pStream);
- return;
- }
- if(grid->get_v_value(gridV+1) >= topVertex[1])
- {
- monoTriangulationRecGenOpt(topVertex, botVertex,
- inc_chain, inc_current, inc_end,
- dec_chain, dec_current, dec_end,
- pStream);
- return;
- }
- Int i,j,k;
- Real currentV = grid->get_v_value(gridV+1);
- if(inc_chain->getVertex(inc_end)[1] <= currentV &&
- dec_chain->getVertex(dec_end)[1] < currentV)
- {
- //find i bottom up so that inc_chain[i]<= curentV and inc_chain[i-1] > currentV,
- //find j botom up so that dec_chain[j] < currentV and dec_chain[j-1] >= currentV
- for(i=inc_end; i >= inc_current; i--)
- {
- if(inc_chain->getVertex(i)[1] > currentV)
- break;
- }
- i++;
- for(j=dec_end; j >= dec_current; j--)
- {
- if(dec_chain->getVertex(j)[1] >= currentV)
- break;
- }
- j++;
- if(inc_chain->getVertex(i)[1] <= dec_chain->getVertex(j)[1])
- {
- //find the k so that dec_chain[k][1] < inc_chain[i][1]
- for(k=j; k<=dec_end; k++)
- {
- if(dec_chain->getVertex(k)[1] < inc_chain->getVertex(i)[1])
- break;
- }
- //we know that dec_chain[j][1] >= inc_chian[i][1]
- //we know that dec_chain[k-1][1]>=inc_chain[i][1]
- //we know that dec_chian[k][1] < inc_chain[i][1]
- //find l in [j, k-1] so that dec_chain[l][0] 0 is closest to
- // inc_chain[i]
- int l;
- Real tempI = Real(j);
- Real tempMin = (Real)fabs(inc_chain->getVertex(i)[0] - dec_chain->getVertex(j)[0]);
- for(l=j+1; l<= k-1; l++)
- {
- if(fabs(inc_chain->getVertex(i)[0] - dec_chain->getVertex(l)[0])
- <= tempMin)
- {
- tempMin = (Real)fabs(inc_chain->getVertex(i)[0] - dec_chain->getVertex(l)[0]);
- tempI = (Real)l;
- }
- }
- //inc_chain[i] and dec_chain[tempI] are connected.
- monoTriangulationRecGenOpt(dec_chain->getVertex((int)tempI),
- botVertex,
- inc_chain, i, inc_end,
- dec_chain, (int)(tempI+1), dec_end,
- pStream);
- //recursively do the rest
- sampleCompTopSimpleOpt(grid,
- gridV+1,
- topVertex, inc_chain->getVertex(i),
- inc_chain, inc_current, i-1,
- dec_chain, dec_current, (int)tempI,
- pStream);
- }
- else
- {
- //find the k so that inc_chain[k][1] <= dec_chain[j][1]
- for(k=i; k<=inc_end; k++)
- {
- if(inc_chain->getVertex(k)[1] <= dec_chain->getVertex(j)[1])
- break;
- }
- //we know that inc_chain[i] > dec_chain[j]
- //we know that inc_chain[k-1][1] > dec_chain[j][1]
- //we know that inc_chain[k][1] <= dec_chain[j][1]
- //so we find l between [i,k-1] so that
- //inc_chain[l][0] is the closet to dec_chain[j][0]
- int tempI = i;
- int l;
- Real tempMin = (Real)fabs(inc_chain->getVertex(i)[0] - dec_chain->getVertex(j)[0]);
- for(l=i+1; l<=k-1; l++)
- {
- if(fabs(inc_chain->getVertex(l)[0] - dec_chain->getVertex(j)[0]) <= tempMin)
- {
- tempMin = (Real)fabs(inc_chain->getVertex(l)[0] - dec_chain->getVertex(j)[0]);
- tempI = l;
- }
- }
-
- //inc_chain[tempI] and dec_chain[j] are connected
-
- monoTriangulationRecGenOpt(inc_chain->getVertex(tempI),
- botVertex,
- inc_chain, tempI+1, inc_end,
- dec_chain, j, dec_end,
- pStream);
-
- //recurvesily do the rest
- sampleCompTopSimpleOpt(grid, gridV+1,
- topVertex, dec_chain->getVertex(j),
- inc_chain, inc_current, tempI,
- dec_chain, dec_current, j-1,
- pStream);
- }
- }
- else //go to the next higher gridV
- {
- sampleCompTopSimpleOpt(grid,
- gridV+1,
- topVertex, botVertex,
- inc_chain, inc_current, inc_end,
- dec_chain, dec_current, dec_end,
- pStream);
- }
-}
-
-void sampleCompTopSimple(Real* topVertex,
- vertexArray* leftChain,
- Int leftStartIndex,
- vertexArray* rightChain,
- Int rightStartIndex,
- gridBoundaryChain* leftGridChain,
- gridBoundaryChain* rightGridChain,
- Int gridIndex1,
- Int up_leftCornerWhere,
- Int up_leftCornerIndex,
- Int up_rightCornerWhere,
- Int up_rightCornerIndex,
- primStream* pStream)
-{
- //the plan is to use monotriangulation algortihm.
- Int i,k;
- Real* ActualTop;
- Real* ActualBot;
- Int ActualLeftStart, ActualLeftEnd;
- Int ActualRightStart, ActualRightEnd;
-
- //creat an array to store the points on the grid line
- gridWrap* grid = leftGridChain->getGrid();
- Int gridV = leftGridChain->getVlineIndex(gridIndex1);
- Int gridLeftU = leftGridChain->getUlineIndex(gridIndex1);
- Int gridRightU = rightGridChain->getUlineIndex(gridIndex1);
-
- Real2* gridPoints = (Real2*) malloc(sizeof(Real2) * (gridRightU - gridLeftU +1));
- assert(gridPoints);
-
- for(k=0, i=gridRightU; i>= gridLeftU; i--, k++)
- {
- gridPoints[k][0] = grid->get_u_value(i);
- gridPoints[k][1] = grid->get_v_value(gridV);
- }
-
- if(up_leftCornerWhere != 2)
- ActualRightStart = rightStartIndex;
- else
- ActualRightStart = up_leftCornerIndex+1; //up_leftCornerIndex will be the ActualTop
-
- if(up_rightCornerWhere != 2) //right corner is not on right chain
- ActualRightEnd = rightStartIndex-1; //meaning that there is no actual rigth section
- else
- ActualRightEnd = up_rightCornerIndex;
-
- vertexArray ActualRightChain(max(0, ActualRightEnd-ActualRightStart+1) + gridRightU-gridLeftU+1);
-
- for(i=ActualRightStart; i<= ActualRightEnd; i++)
- ActualRightChain.appendVertex(rightChain->getVertex(i));
- for(i=0; i<gridRightU-gridLeftU+1; i++)
- ActualRightChain.appendVertex(gridPoints[i]);
-
- //determine ActualLeftEnd
- if(up_leftCornerWhere != 0)
- ActualLeftEnd = leftStartIndex-1;
- else
- ActualLeftEnd = up_leftCornerIndex;
-
- if(up_rightCornerWhere != 0)
- ActualLeftStart = leftStartIndex;
- else
- ActualLeftStart = up_rightCornerIndex+1; //up_rightCornerIndex will be the actual top
-
- if(up_leftCornerWhere == 0)
- {
- if(up_rightCornerWhere == 0)
- ActualTop = leftChain->getVertex(up_rightCornerIndex);
- else
- ActualTop = topVertex;
- }
- else if(up_leftCornerWhere == 1)
- ActualTop = topVertex;
- else //up_leftCornerWhere == 2
- ActualTop = rightChain->getVertex(up_leftCornerIndex);
-
- ActualBot = gridPoints[gridRightU - gridLeftU];
-
-
-
-
- if(leftChain->getVertex(ActualLeftEnd)[1] == ActualBot[1])
- {
-/*
- monoTriangulationRecGenOpt(ActualTop, leftChain->getVertex(ActualLeftEnd),
- leftChain,
- ActualLeftStart, ActualLeftEnd-1,
- &ActualRightChain,
- 0,
- ActualRightChain.getNumElements()-1,
- pStream);
-*/
-
- sampleCompTopSimpleOpt(grid, gridV,
- ActualTop, leftChain->getVertex(ActualLeftEnd),
- leftChain,
- ActualLeftStart, ActualLeftEnd-1,
- &ActualRightChain,
- 0,
- ActualRightChain.getNumElements()-1,
- pStream);
-
- }
- else
- {
-/*
- monoTriangulationRecGenOpt(ActualTop, ActualBot, leftChain,
- ActualLeftStart, ActualLeftEnd,
- &ActualRightChain,
- 0, ActualRightChain.getNumElements()-2, //the last is the bot.
- pStream);
-*/
-
- sampleCompTopSimpleOpt(grid, gridV,
- ActualTop, ActualBot, leftChain,
- ActualLeftStart, ActualLeftEnd,
- &ActualRightChain,
- 0, ActualRightChain.getNumElements()-2, //the last is the bot.
- pStream);
-
-
- }
-
- free(gridPoints);
-
-}
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-#ifndef _SAMPLECOMPTOP_H
-#define _SAMPLECOMPTOP_H
-
-#include "sampleMonoPoly.h"
-
-void sampleCompTop(Real* topVertex,
- vertexArray* leftChain,
- Int leftStartIndex,
- vertexArray* rightChain,
- Int rightStartIndex,
- gridBoundaryChain* leftGridChain,
- gridBoundaryChain* rightGridChain,
- Int gridIndex1,
- Int up_leftCornerWhere,
- Int up_leftCornerIndex,
- Int up_rightCornerWhere,
- Int up_rightCornerIndex,
- primStream* pStream);
-
-void sampleCompTopSimple(Real* topVertex,
- vertexArray* leftChain,
- Int leftStartIndex,
- vertexArray* rightChain,
- Int rightStartIndex,
- gridBoundaryChain* leftGridChain,
- gridBoundaryChain* rightGridChain,
- Int gridIndex1,
- Int up_leftCornerWhere,
- Int up_leftCornerIndex,
- Int up_rightCornerWhere,
- Int up_rightCornerIndex,
- primStream* pStream);
-
-#endif
-
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include "gluos.h"
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-
-#ifndef max
-#define max(a,b) ((a>b)? a:b)
-#endif
-#ifndef min
-#define min(a,b) ((a>b)? b:a)
-#endif
-
-#include <GL/gl.h>
-
-#include "glimports.h"
-#include "zlassert.h"
-#include "sampleMonoPoly.h"
-#include "sampleComp.h"
-#include "polyDBG.h"
-#include "partitionX.h"
-
-
-#define ZERO 0.00001
-
-//#define MYDEBUG
-
-//#define SHORTEN_GRID_LINE
-//see work/newtess/internal/test/problems
-
-
-/*split a polygon so that each vertex correcpond to one edge
- *the head of the first edge of the returned plygon must be the head of the first
- *edge of the origianl polygon. This is crucial for the code in sampleMonoPoly function
- */
- directedLine* polygonConvert(directedLine* polygon)
-{
- int i;
- directedLine* ret;
- sampledLine* sline;
- sline = new sampledLine(2);
- sline->setPoint(0, polygon->getVertex(0));
- sline->setPoint(1, polygon->getVertex(1));
- ret=new directedLine(INCREASING, sline);
- for(i=1; i<= polygon->get_npoints()-2; i++)
- {
- sline = new sampledLine(2);
- sline->setPoint(0, polygon->getVertex(i));
- sline->setPoint(1, polygon->getVertex(i+1));
- ret->insert(new directedLine(INCREASING, sline));
- }
-
- for(directedLine *temp = polygon->getNext(); temp != polygon; temp = temp->getNext())
- {
- for(i=0; i<= temp->get_npoints()-2; i++)
- {
- sline = new sampledLine(2);
- sline->setPoint(0, temp->getVertex(i));
- sline->setPoint(1, temp->getVertex(i+1));
- ret->insert(new directedLine(INCREASING, sline));
- }
- }
- return ret;
-}
-
-void triangulateConvexPolyVertical(directedLine* topV, directedLine* botV, primStream *pStream)
-{
- Int i,j;
- Int n_leftVerts;
- Int n_rightVerts;
- Real** leftVerts;
- Real** rightVerts;
- directedLine* tempV;
- n_leftVerts = 0;
- for(tempV = topV; tempV != botV; tempV = tempV->getNext())
- {
- n_leftVerts += tempV->get_npoints();
- }
- n_rightVerts=0;
- for(tempV = botV; tempV != topV; tempV = tempV->getNext())
- {
- n_rightVerts += tempV->get_npoints();
- }
-
- Real2* temp_leftVerts = (Real2 *) malloc(sizeof(Real2) * n_leftVerts);
- assert(temp_leftVerts);
- Real2* temp_rightVerts = (Real2 *) malloc(sizeof(Real2) * n_rightVerts);
- assert(temp_rightVerts);
-
- leftVerts = (Real**) malloc(sizeof(Real2*) * n_leftVerts);
- assert(leftVerts);
- rightVerts = (Real**) malloc(sizeof(Real2*) * n_rightVerts);
- assert(rightVerts);
- for(i=0; i<n_leftVerts; i++)
- leftVerts[i] = temp_leftVerts[i];
- for(i=0; i<n_rightVerts; i++)
- rightVerts[i] = temp_rightVerts[i];
-
- i=0;
- for(tempV = topV; tempV != botV; tempV = tempV->getNext())
- {
- for(j=1; j<tempV->get_npoints(); j++)
- {
- leftVerts[i][0] = tempV->getVertex(j)[0];
- leftVerts[i][1] = tempV->getVertex(j)[1];
- i++;
- }
- }
- n_leftVerts = i;
- i=0;
- for(tempV = topV->getPrev(); tempV != botV->getPrev(); tempV = tempV->getPrev())
- {
- for(j=tempV->get_npoints()-1; j>=1; j--)
- {
- rightVerts[i][0] = tempV->getVertex(j)[0];
- rightVerts[i][1] = tempV->getVertex(j)[1];
- i++;
- }
- }
- n_rightVerts = i;
- triangulateXYMonoTB(n_leftVerts, leftVerts, n_rightVerts, rightVerts, pStream);
- free(leftVerts);
- free(rightVerts);
- free(temp_leftVerts);
- free(temp_rightVerts);
-}
-
-void triangulateConvexPolyHoriz(directedLine* leftV, directedLine* rightV, primStream *pStream)
-{
- Int i,j;
- Int n_lowerVerts;
- Int n_upperVerts;
- Real2 *lowerVerts;
- Real2 *upperVerts;
- directedLine* tempV;
- n_lowerVerts=0;
- for(tempV = leftV; tempV != rightV; tempV = tempV->getNext())
- {
- n_lowerVerts += tempV->get_npoints();
- }
- n_upperVerts=0;
- for(tempV = rightV; tempV != leftV; tempV = tempV->getNext())
- {
- n_upperVerts += tempV->get_npoints();
- }
- lowerVerts = (Real2 *) malloc(sizeof(Real2) * n_lowerVerts);
- assert(n_lowerVerts);
- upperVerts = (Real2 *) malloc(sizeof(Real2) * n_upperVerts);
- assert(n_upperVerts);
- i=0;
- for(tempV = leftV; tempV != rightV; tempV = tempV->getNext())
- {
- for(j=0; j<tempV->get_npoints(); j++)
- {
- lowerVerts[i][0] = tempV->getVertex(j)[0];
- lowerVerts[i][1] = tempV->getVertex(j)[1];
- i++;
- }
- }
- i=0;
- for(tempV = leftV->getPrev(); tempV != rightV->getPrev(); tempV = tempV->getPrev())
- {
- for(j=tempV->get_npoints()-1; j>=0; j--)
- {
- upperVerts[i][0] = tempV->getVertex(j)[0];
- upperVerts[i][1] = tempV->getVertex(j)[1];
- i++;
- }
- }
- triangulateXYMono(n_upperVerts, upperVerts, n_lowerVerts, lowerVerts, pStream);
- free(lowerVerts);
- free(upperVerts);
-}
-void triangulateConvexPoly(directedLine* polygon, Int ulinear, Int vlinear, primStream* pStream)
-{
- /*find left, right, top , bot
- */
- directedLine* tempV;
- directedLine* topV;
- directedLine* botV;
- directedLine* leftV;
- directedLine* rightV;
- topV = botV = polygon;
-
- for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext())
- {
- if(compV2InY(topV->head(), tempV->head())<0) {
-
- topV = tempV;
- }
- if(compV2InY(botV->head(), tempV->head())>0) {
-
- botV = tempV;
- }
- }
- //find leftV
- for(tempV = topV; tempV != botV; tempV = tempV->getNext())
- {
- if(tempV->tail()[0] >= tempV->head()[0])
- break;
- }
- leftV = tempV;
- //find rightV
- for(tempV = botV; tempV != topV; tempV = tempV->getNext())
- {
- if(tempV->tail()[0] <= tempV->head()[0])
- break;
- }
- rightV = tempV;
- if(vlinear)
- {
- triangulateConvexPolyHoriz( leftV, rightV, pStream);
- }
- else if(ulinear)
- {
- triangulateConvexPolyVertical(topV, botV, pStream);
- }
- else
- {
- if(DBG_is_U_direction(polygon))
- {
- triangulateConvexPolyHoriz( leftV, rightV, pStream);
- }
- else
- triangulateConvexPolyVertical(topV, botV, pStream);
- }
-}
-
-/*for debug purpose*/
-void drawCorners(
- Real* topV, Real* botV,
- vertexArray* leftChain,
- vertexArray* rightChain,
- gridBoundaryChain* leftGridChain,
- gridBoundaryChain* rightGridChain,
- Int gridIndex1,
- Int gridIndex2,
- Int leftCornerWhere,
- Int leftCornerIndex,
- Int rightCornerWhere,
- Int rightCornerIndex,
- Int bot_leftCornerWhere,
- Int bot_leftCornerIndex,
- Int bot_rightCornerWhere,
- Int bot_rightCornerIndex)
-{
- Real* leftCornerV;
- Real* rightCornerV;
- Real* bot_leftCornerV;
- Real* bot_rightCornerV;
-
- if(leftCornerWhere == 1)
- leftCornerV = topV;
- else if(leftCornerWhere == 0)
- leftCornerV = leftChain->getVertex(leftCornerIndex);
- else
- leftCornerV = rightChain->getVertex(leftCornerIndex);
-
- if(rightCornerWhere == 1)
- rightCornerV = topV;
- else if(rightCornerWhere == 0)
- rightCornerV = leftChain->getVertex(rightCornerIndex);
- else
- rightCornerV = rightChain->getVertex(rightCornerIndex);
-
- if(bot_leftCornerWhere == 1)
- bot_leftCornerV = botV;
- else if(bot_leftCornerWhere == 0)
- bot_leftCornerV = leftChain->getVertex(bot_leftCornerIndex);
- else
- bot_leftCornerV = rightChain->getVertex(bot_leftCornerIndex);
-
- if(bot_rightCornerWhere == 1)
- bot_rightCornerV = botV;
- else if(bot_rightCornerWhere == 0)
- bot_rightCornerV = leftChain->getVertex(bot_rightCornerIndex);
- else
- bot_rightCornerV = rightChain->getVertex(bot_rightCornerIndex);
-
- Real topGridV = leftGridChain->get_v_value(gridIndex1);
- Real topGridU1 = leftGridChain->get_u_value(gridIndex1);
- Real topGridU2 = rightGridChain->get_u_value(gridIndex1);
- Real botGridV = leftGridChain->get_v_value(gridIndex2);
- Real botGridU1 = leftGridChain->get_u_value(gridIndex2);
- Real botGridU2 = rightGridChain->get_u_value(gridIndex2);
-
- glBegin(GL_LINE_STRIP);
- glVertex2fv(leftCornerV);
- glVertex2f(topGridU1, topGridV);
- glEnd();
-
- glBegin(GL_LINE_STRIP);
- glVertex2fv(rightCornerV);
- glVertex2f(topGridU2, topGridV);
- glEnd();
-
- glBegin(GL_LINE_STRIP);
- glVertex2fv(bot_leftCornerV);
- glVertex2f(botGridU1, botGridV);
- glEnd();
-
- glBegin(GL_LINE_STRIP);
- glVertex2fv(bot_rightCornerV);
- glVertex2f(botGridU2, botGridV);
- glEnd();
-
-
-}
-
-void toVertexArrays(directedLine* topV, directedLine* botV, vertexArray& leftChain, vertexArray& rightChain)
-{
- Int i;
- directedLine* tempV;
- for(i=1; i<=topV->get_npoints()-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/
- leftChain.appendVertex(topV->getVertex(i));
- }
- for(tempV = topV->getNext(); tempV != botV; tempV = tempV->getNext())
- {
- for(i=0; i<=tempV->get_npoints()-2; i++){
- leftChain.appendVertex(tempV->getVertex(i));
- }
- }
-
- for(tempV = topV->getPrev(); tempV != botV; tempV = tempV->getPrev())
- {
- for(i=tempV->get_npoints()-2; i>=0; i--){
- rightChain.appendVertex(tempV->getVertex(i));
- }
- }
- for(i=botV->get_npoints()-2; i>=1; i--){
- rightChain.appendVertex(tempV->getVertex(i));
- }
-}
-
-
-void findTopAndBot(directedLine* polygon, directedLine*& topV, directedLine*& botV)
-{
- assert(polygon);
- directedLine* tempV;
- topV = botV = polygon;
- for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext())
- {
- if(compV2InY(topV->head(), tempV->head())<0) {
- topV = tempV;
- }
- if(compV2InY(botV->head(), tempV->head())>0) {
- botV = tempV;
- }
- }
-}
-
-void findGridChains(directedLine* topV, directedLine* botV,
- gridWrap* grid,
- gridBoundaryChain*& leftGridChain,
- gridBoundaryChain*& rightGridChain)
-{
- /*find the first(top) and the last (bottom) grid line which intersect the
- *this polygon
- */
- Int firstGridIndex; /*the index in the grid*/
- Int lastGridIndex;
-
- firstGridIndex = (Int) ((topV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1));
-
- if(botV->head()[1] < grid->get_v_min())
- lastGridIndex = 0;
- else
- lastGridIndex = (Int) ((botV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1)) + 1;
-
- /*find the interval inside the polygon for each gridline*/
- Int *leftGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
- assert(leftGridIndices);
- Int *rightGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
- assert(rightGridIndices);
- Int *leftGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
- assert(leftGridInnerIndices);
- Int *rightGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
- assert(rightGridInnerIndices);
-
- findLeftGridIndices(topV, firstGridIndex, lastGridIndex, grid, leftGridIndices, leftGridInnerIndices);
-
- findRightGridIndices(topV, firstGridIndex, lastGridIndex, grid, rightGridIndices, rightGridInnerIndices);
-
- leftGridChain = new gridBoundaryChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, leftGridIndices, leftGridInnerIndices);
-
- rightGridChain = new gridBoundaryChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, rightGridIndices, rightGridInnerIndices);
-
- free(leftGridIndices);
- free(rightGridIndices);
- free(leftGridInnerIndices);
- free(rightGridInnerIndices);
-}
-
-void findDownCorners(Real *botVertex,
- vertexArray *leftChain, Int leftChainStartIndex, Int leftChainEndIndex,
- vertexArray *rightChain, Int rightChainStartIndex, Int rightChainEndIndex,
- Real v,
- Real uleft,
- Real uright,
- Int& ret_leftCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/
- Int& ret_leftCornerIndex, /*useful when ret_leftCornerWhere == 0 or 2*/
- Int& ret_rightCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/
- Int& ret_rightCornerIndex /*useful when ret_leftCornerWhere == 0 or 2*/
- )
-{
-#ifdef MYDEBUG
-printf("*************enter find donw corner\n");
-printf("finddownCorner: v=%f, uleft=%f, uright=%f\n", v, uleft, uright);
-printf("(%i,%i,%i,%i)\n", leftChainStartIndex, leftChainEndIndex,rightChainStartIndex, rightChainEndIndex);
-printf("left chain is\n");
-leftChain->print();
-printf("right chain is\n");
-rightChain->print();
-#endif
-
- assert(v > botVertex[1]);
- Real leftGridPoint[2];
- leftGridPoint[0] = uleft;
- leftGridPoint[1] = v;
- Real rightGridPoint[2];
- rightGridPoint[0] = uright;
- rightGridPoint[1] = v;
-
- Int i;
- Int index1, index2;
-
- index1 = leftChain->findIndexBelowGen(v, leftChainStartIndex, leftChainEndIndex);
- index2 = rightChain->findIndexBelowGen(v, rightChainStartIndex, rightChainEndIndex);
-
- if(index2 <= rightChainEndIndex) //index2 was found above
- index2 = rightChain->skipEqualityFromStart(v, index2, rightChainEndIndex);
-
- if(index1>leftChainEndIndex && index2 > rightChainEndIndex) /*no point below v on left chain or right chain*/
- {
-
- /*the botVertex is the only vertex below v*/
- ret_leftCornerWhere = 1;
- ret_rightCornerWhere = 1;
- }
- else if(index1>leftChainEndIndex ) /*index2 <= rightChainEndIndex*/
- {
-
- ret_rightCornerWhere = 2; /*on right chain*/
- ret_rightCornerIndex = index2;
-
-
- Real tempMin = rightChain->getVertex(index2)[0];
- Int tempI = index2;
- for(i=index2+1; i<= rightChainEndIndex; i++)
- if(rightChain->getVertex(i)[0] < tempMin)
- {
- tempI = i;
- tempMin = rightChain->getVertex(i)[0];
- }
-
-
- //we consider whether we can use botVertex as left corner. First check
- //if (leftGirdPoint, botVertex) interesects right chian or not.
- if(DBG_intersectChain(rightChain, rightChainStartIndex,rightChainEndIndex,
- leftGridPoint, botVertex))
- {
- ret_leftCornerWhere = 2;//right
- ret_leftCornerIndex = index2; //should use tempI???
- }
- else if(botVertex[0] < tempMin)
- ret_leftCornerWhere = 1; //bot
- else
- {
- ret_leftCornerWhere = 2; //right
- ret_leftCornerIndex = tempI;
- }
- }
- else if(index2> rightChainEndIndex) /*index1<=leftChainEndIndex*/
- {
- ret_leftCornerWhere = 0; /*left chain*/
- ret_leftCornerIndex = index1;
-
- /*find the vertex on the left chain with the maximum u,
- *either this vertex or the botvertex can be used as the right corner
- */
-
- Int tempI;
- //skip those points which are equal to v. (avoid degeneratcy)
- for(tempI = index1; tempI <= leftChainEndIndex; tempI++)
- if(leftChain->getVertex(tempI)[1] < v)
- break;
- if(tempI > leftChainEndIndex)
- ret_rightCornerWhere = 1;
- else
- {
- Real tempMax = leftChain->getVertex(tempI)[0];
- for(i=tempI; i<= leftChainEndIndex; i++)
- if(leftChain->getVertex(i)[0] > tempMax)
- {
- tempI = i;
- tempMax = leftChain->getVertex(i)[0];
- }
-
-
-
- //we consider whether we can use botVertex as a corner. So first we check
- //whether (rightGridPoint, botVertex) interescts the left chain or not.
- if(DBG_intersectChain(leftChain, leftChainStartIndex,leftChainEndIndex,
- rightGridPoint, botVertex))
- {
- ret_rightCornerWhere = 0;
- ret_rightCornerIndex = index1; //should use tempI???
- }
- else if(botVertex[0] > tempMax)
- {
-
- ret_rightCornerWhere = 1;
- }
- else
- {
- ret_rightCornerWhere = 0;
- ret_rightCornerIndex = tempI;
- }
- }
-
- }
- else /*index1<=leftChainEndIndex and index2 <=rightChainEndIndex*/
- {
- if(leftChain->getVertex(index1)[1] >= rightChain->getVertex(index2)[1]) /*left point above right point*/
- {
- ret_leftCornerWhere = 0; /*on left chain*/
- ret_leftCornerIndex = index1;
-
- Real tempMax;
- Int tempI;
-
- tempI = index1;
- tempMax = leftChain->getVertex(index1)[0];
-
- /*find the maximum u for all the points on the left above the right point index2*/
- for(i=index1+1; i<= leftChainEndIndex; i++)
- {
- if(leftChain->getVertex(i)[1] < rightChain->getVertex(index2)[1])
- break;
-
- if(leftChain->getVertex(i)[0]>tempMax)
- {
- tempI = i;
- tempMax = leftChain->getVertex(i)[0];
- }
- }
- //we consider if we can use rightChain(index2) as right corner
- //we check if (rightChain(index2), rightGidPoint) intersecs left chain or not.
- if(DBG_intersectChain(leftChain, leftChainStartIndex,leftChainEndIndex, rightGridPoint, rightChain->getVertex(index2)))
- {
- ret_rightCornerWhere = 0;
- ret_rightCornerIndex = index1; //should use tempI???
- }
- else if(tempMax >= rightChain->getVertex(index2)[0] ||
- tempMax >= uright
- )
- {
-
- ret_rightCornerWhere = 0; /*on left Chain*/
- ret_rightCornerIndex = tempI;
- }
- else
- {
- ret_rightCornerWhere = 2; /*on right chain*/
- ret_rightCornerIndex = index2;
- }
- }
- else /*left below right*/
- {
- ret_rightCornerWhere = 2; /*on the right*/
- ret_rightCornerIndex = index2;
-
- Real tempMin;
- Int tempI;
-
- tempI = index2;
- tempMin = rightChain->getVertex(index2)[0];
-
- /*find the minimum u for all the points on the right above the left poitn index1*/
- for(i=index2+1; i<= rightChainEndIndex; i++)
- {
- if( rightChain->getVertex(i)[1] < leftChain->getVertex(index1)[1])
- break;
- if(rightChain->getVertex(i)[0] < tempMin)
- {
- tempI = i;
- tempMin = rightChain->getVertex(i)[0];
- }
- }
-
- //we consider if we can use leftchain(index1) as left corner.
- //we check if (leftChain(index1) intersects right chian or not
- if(DBG_intersectChain(rightChain, rightChainStartIndex, rightChainEndIndex, leftGridPoint, leftChain->getVertex(index1)))
- {
- ret_leftCornerWhere = 2;
- ret_leftCornerIndex = index2; //should use tempI???
- }
- else if(tempMin <= leftChain->getVertex(index1)[0] ||
- tempMin <= uleft)
- {
- ret_leftCornerWhere = 2; /* on right chain*/
- ret_leftCornerIndex = tempI;
- }
- else
- {
- ret_leftCornerWhere = 0; /*on left chain*/
- ret_leftCornerIndex = index1;
- }
- }
- }
-
-}
-
-
-void findUpCorners(Real *topVertex,
- vertexArray *leftChain, Int leftChainStartIndex, Int leftChainEndIndex,
- vertexArray *rightChain, Int rightChainStartIndex, Int rightChainEndIndex,
- Real v,
- Real uleft,
- Real uright,
- Int& ret_leftCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/
- Int& ret_leftCornerIndex, /*useful when ret_leftCornerWhere == 0 or 2*/
- Int& ret_rightCornerWhere, /*0: left chain, 1: topvertex, 2: rightchain*/
- Int& ret_rightCornerIndex /*useful when ret_leftCornerWhere == 0 or 2*/
- )
-{
-#ifdef MYDEBUG
-printf("***********enter findUpCorners\n");
-#endif
-
- assert(v < topVertex[1]);
- Real leftGridPoint[2];
- leftGridPoint[0] = uleft;
- leftGridPoint[1] = v;
- Real rightGridPoint[2];
- rightGridPoint[0] = uright;
- rightGridPoint[1] = v;
-
- Int i;
- Int index1, index2;
-
- index1 = leftChain->findIndexFirstAboveEqualGen(v, leftChainStartIndex, leftChainEndIndex);
-
-
- index2 = rightChain->findIndexFirstAboveEqualGen(v, rightChainStartIndex, rightChainEndIndex);
-
- if(index2>= leftChainStartIndex) //index2 was found above
- index2 = rightChain->skipEqualityFromStart(v, index2, rightChainEndIndex);
-
- if(index1<leftChainStartIndex && index2 <rightChainStartIndex) /*no point above v on left chain or right chain*/
- {
- /*the topVertex is the only vertex above v*/
- ret_leftCornerWhere = 1;
- ret_rightCornerWhere = 1;
- }
- else if(index1<leftChainStartIndex ) /*index2 >= rightChainStartIndex*/
- {
- ret_rightCornerWhere = 2; /*on right chain*/
- ret_rightCornerIndex = index2;
-
- //find the minimum u on right top, either that, or top, or right[index2] is the left corner
- Real tempMin = rightChain->getVertex(index2)[0];
- Int tempI = index2;
- for(i=index2-1; i>=rightChainStartIndex; i--)
- if(rightChain->getVertex(i)[0] < tempMin)
- {
- tempMin = rightChain->getVertex(i)[0];
- tempI = i;
- }
- //chech whether (leftGridPoint, top) intersects rightchai,
- //if yes, use right corner as left corner
- //if not, use top or right[tempI] as left corner
- if(DBG_intersectChain(rightChain, rightChainStartIndex, rightChainEndIndex,
- leftGridPoint, topVertex))
- {
- ret_leftCornerWhere = 2; //rightChain
- ret_leftCornerIndex = index2;
- }
- else if(topVertex[0] < tempMin)
- ret_leftCornerWhere = 1; /*topvertex*/
- else
- {
- ret_leftCornerWhere = 2; //right chain
- ret_leftCornerIndex = tempI;
- }
-
- }
- else if(index2< rightChainStartIndex) /*index1>=leftChainStartIndex*/
- {
- ret_leftCornerWhere = 0; /*left chain*/
- ret_leftCornerIndex = index1;
-
- //find the maximum u on the left top section. either that or topvertex, or left[index1] is the right corner
- Real tempMax = leftChain->getVertex(index1)[0];
- Int tempI = index1;
-
- for(i=index1-1; i>=leftChainStartIndex; i--){
-
- if(leftChain->getVertex(i)[0] > tempMax)
- {
-
- tempMax = leftChain->getVertex(i)[0];
- tempI = i;
- }
- }
- //check whether (rightGridPoint, top) intersects leftChain or not
- //if yes, we use leftCorner as the right corner
- //if not, we use either top or left[tempI] as the right corner
- if(DBG_intersectChain(leftChain, leftChainStartIndex,leftChainEndIndex,
- rightGridPoint, topVertex))
- {
- ret_rightCornerWhere = 0; //left chan
- ret_rightCornerIndex = index1;
- }
- else if(topVertex[0] > tempMax)
- ret_rightCornerWhere = 1;//topVertex
- else
- {
- ret_rightCornerWhere = 0;//left chain
- ret_rightCornerIndex = tempI;
- }
- }
- else /*index1>=leftChainStartIndex and index2 >=rightChainStartIndex*/
- {
- if(leftChain->getVertex(index1)[1] <= rightChain->getVertex(index2)[1]) /*left point below right point*/
- {
- ret_leftCornerWhere = 0; /*on left chain*/
- ret_leftCornerIndex = index1;
-
- Real tempMax;
- Int tempI;
-
- tempI = index1;
- tempMax = leftChain->getVertex(index1)[0];
-
- /*find the maximum u for all the points on the left below the right point index2*/
- for(i=index1-1; i>= leftChainStartIndex; i--)
- {
- if(leftChain->getVertex(i)[1] > rightChain->getVertex(index2)[1])
- break;
-
- if(leftChain->getVertex(i)[0]>tempMax)
- {
- tempI = i;
- tempMax = leftChain->getVertex(i)[0];
- }
- }
- //chek whether (rightChain(index2), rightGridPoint) intersects leftchian or not
- if(DBG_intersectChain(leftChain, leftChainStartIndex, leftChainEndIndex, rightGridPoint, rightChain->getVertex(index2)))
- {
- ret_rightCornerWhere = 0;
- ret_rightCornerIndex = index1;
- }
- else if(tempMax >= rightChain->getVertex(index2)[0] ||
- tempMax >= uright)
- {
- ret_rightCornerWhere = 0; /*on left Chain*/
- ret_rightCornerIndex = tempI;
- }
- else
- {
- ret_rightCornerWhere = 2; /*on right chain*/
- ret_rightCornerIndex = index2;
- }
- }
- else /*left above right*/
- {
- ret_rightCornerWhere = 2; /*on the right*/
- ret_rightCornerIndex = index2;
-
- Real tempMin;
- Int tempI;
-
- tempI = index2;
- tempMin = rightChain->getVertex(index2)[0];
-
- /*find the minimum u for all the points on the right below the left poitn index1*/
- for(i=index2-1; i>= rightChainStartIndex; i--)
- {
- if( rightChain->getVertex(i)[1] > leftChain->getVertex(index1)[1])
- break;
- if(rightChain->getVertex(i)[0] < tempMin)
- {
- tempI = i;
- tempMin = rightChain->getVertex(i)[0];
- }
- }
- //check whether (leftGRidPoint,left(index1)) interesect right chain
- if(DBG_intersectChain(rightChain, rightChainStartIndex, rightChainEndIndex,
- leftGridPoint, leftChain->getVertex(index1)))
- {
- ret_leftCornerWhere = 2; //right
- ret_leftCornerIndex = index2;
- }
- else if(tempMin <= leftChain->getVertex(index1)[0] ||
- tempMin <= uleft)
- {
- ret_leftCornerWhere = 2; /* on right chain*/
- ret_leftCornerIndex = tempI;
- }
- else
- {
- ret_leftCornerWhere = 0; /*on left chain*/
- ret_leftCornerIndex = index1;
- }
- }
- }
-#ifdef MYDEBUG
-printf("***********leave findUpCorners\n");
-#endif
-}
-
-//return 1 if neck exists, 0 othewise
-Int findNeckF(vertexArray *leftChain, Int botLeftIndex,
- vertexArray *rightChain, Int botRightIndex,
- gridBoundaryChain* leftGridChain,
- gridBoundaryChain* rightGridChain,
- Int gridStartIndex,
- Int& neckLeft,
- Int& neckRight)
-{
-/*
-printf("enter findNeckF, botleft, botright=%i,%i,gstartindex=%i\n",botLeftIndex,botRightIndex,gridStartIndex);
-printf("leftChain is\n");
-leftChain->print();
-printf("rightChain is\n");
-rightChain->print();
-*/
-
- Int lowerGridIndex; //the grid below leftChain and rightChian vertices
- Int i;
- Int n_vlines = leftGridChain->get_nVlines();
- Real v;
- if(botLeftIndex >= leftChain->getNumElements() ||
- botRightIndex >= rightChain->getNumElements())
- return 0; //no neck exists
-
- v=min(leftChain->getVertex(botLeftIndex)[1], rightChain->getVertex(botRightIndex)[1]);
-
-
-
-
- for(i=gridStartIndex; i<n_vlines; i++)
- if(leftGridChain->get_v_value(i) <= v &&
- leftGridChain->getUlineIndex(i)<= rightGridChain->getUlineIndex(i))
- break;
-
- lowerGridIndex = i;
-
- if(lowerGridIndex == n_vlines) //the two trm vertex are higher than all gridlines
- return 0;
- else
- {
- Int botLeft2, botRight2;
-/*
-printf("leftGridChain->get_v_)value=%f\n",leftGridChain->get_v_value(lowerGridIndex), botLeftIndex);
-printf("leftChain->get_vertex(0)=(%f,%f)\n", leftChain->getVertex(0)[0],leftChain->getVertex(0)[1]);
-printf("leftChain->get_vertex(1)=(%f,%f)\n", leftChain->getVertex(1)[0],leftChain->getVertex(1)[1]);
-printf("leftChain->get_vertex(2)=(%f,%f)\n", leftChain->getVertex(2)[0],leftChain->getVertex(2)[1]);
-*/
- botLeft2 = leftChain->findIndexFirstAboveEqualGen(leftGridChain->get_v_value(lowerGridIndex), botLeftIndex, leftChain->getNumElements()-1) -1 ;
-
-/*
-printf("botLeft2=%i\n", botLeft2);
-printf("leftChain->getNumElements=%i\n", leftChain->getNumElements());
-*/
-
- botRight2 = rightChain->findIndexFirstAboveEqualGen(leftGridChain->get_v_value(lowerGridIndex), botRightIndex, rightChain->getNumElements()-1) -1;
- if(botRight2 < botRightIndex) botRight2=botRightIndex;
-
- if(botLeft2 < botLeftIndex) botLeft2 = botLeftIndex;
-
- assert(botLeft2 >= botLeftIndex);
- assert(botRight2 >= botRightIndex);
- //find nectLeft so that it is th erightmost vertex on letChain
-
- Int tempI = botLeftIndex;
- Real temp = leftChain->getVertex(tempI)[0];
- for(i=botLeftIndex+1; i<= botLeft2; i++)
- if(leftChain->getVertex(i)[0] > temp)
- {
- temp = leftChain->getVertex(i)[0];
- tempI = i;
- }
- neckLeft = tempI;
-
- tempI = botRightIndex;
- temp = rightChain->getVertex(tempI)[0];
- for(i=botRightIndex+1; i<= botRight2; i++)
- if(rightChain->getVertex(i)[0] < temp)
- {
- temp = rightChain->getVertex(i)[0];
- tempI = i;
- }
- neckRight = tempI;
- return 1;
- }
-}
-
-
-
-/*find i>=botLeftIndex,j>=botRightIndex so that
- *(leftChain[i], rightChain[j]) is a neck.
- */
-void findNeck(vertexArray *leftChain, Int botLeftIndex,
- vertexArray *rightChain, Int botRightIndex,
- Int& leftLastIndex, /*left point of the neck*/
- Int& rightLastIndex /*right point of the neck*/
- )
-{
- assert(botLeftIndex < leftChain->getNumElements() &&
- botRightIndex < rightChain->getNumElements());
-
- /*now the neck exists for sure*/
-
- if(leftChain->getVertex(botLeftIndex)[1] <= rightChain->getVertex(botRightIndex)[1]) //left below right
- {
-
- leftLastIndex = botLeftIndex;
-
- /*find i so that rightChain[i][1] >= leftchainbotverte[1], and i+1<
- */
- rightLastIndex=rightChain->findIndexAboveGen(leftChain->getVertex(botLeftIndex)[1], botRightIndex+1, rightChain->getNumElements()-1);
- }
- else //left above right
- {
-
- rightLastIndex = botRightIndex;
-
- leftLastIndex = leftChain->findIndexAboveGen(rightChain->getVertex(botRightIndex)[1],
- botLeftIndex+1,
- leftChain->getNumElements()-1);
- }
-}
-
-
-
-void findLeftGridIndices(directedLine* topEdge, Int firstGridIndex, Int lastGridIndex, gridWrap* grid, Int* ret_indices, Int* ret_innerIndices)
-{
-
- Int i,k,isHoriz = 0;
- Int n_ulines = grid->get_n_ulines();
- Real uMin = grid->get_u_min();
- Real uMax = grid->get_u_max();
- /*
- Real vMin = grid->get_v_min();
- Real vMax = grid->get_v_max();
- */
- Real slop = 0.0, uinterc;
-
-#ifdef SHORTEN_GRID_LINE
- //uintercBuf stores all the interction u value for each grid line
- //notice that lastGridIndex<= firstGridIndex
- Real *uintercBuf = (Real *) malloc (sizeof(Real) * (firstGridIndex-lastGridIndex+1));
- assert(uintercBuf);
-#endif
-
- /*initialization to make vtail bigger than grid->...*/
- directedLine* dLine = topEdge;
- Real vtail = grid->get_v_value(firstGridIndex) + 1.0;
- Real tempMaxU = grid->get_u_min();
-
-
- /*for each grid line*/
- for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++)
- {
-
- Real grid_v_value = grid->get_v_value(i);
-
- /*check whether this grid line is below the current trim edge.*/
- if(vtail > grid_v_value)
- {
- /*since the grid line is below the trim edge, we
- *find the trim edge which will contain the trim line
- */
- while( (vtail=dLine->tail()[1]) > grid_v_value){
-
- tempMaxU = max(tempMaxU, dLine->tail()[0]);
- dLine = dLine -> getNext();
- }
-
- if( fabs(dLine->head()[1] - vtail) < ZERO)
- isHoriz = 1;
- else
- {
- isHoriz = 0;
- slop = (dLine->head()[0] - dLine->tail()[0]) / (dLine->head()[1]-vtail);
- }
- }
-
- if(isHoriz)
- {
- uinterc = max(dLine->head()[0], dLine->tail()[0]);
- }
- else
- {
- uinterc = slop * (grid_v_value - vtail) + dLine->tail()[0];
- }
-
- tempMaxU = max(tempMaxU, uinterc);
-
- if(uinterc < uMin && uinterc >= uMin - ZERO)
- uinterc = uMin;
- if(uinterc > uMax && uinterc <= uMax + ZERO)
- uinterc = uMax;
-
-#ifdef SHORTEN_GRID_LINE
- uintercBuf[k] = uinterc;
-#endif
-
- assert(uinterc >= uMin && uinterc <= uMax);
- if(uinterc == uMax)
- ret_indices[k] = n_ulines-1;
- else
- ret_indices[k] = (Int)(((uinterc-uMin)/(uMax - uMin)) * (n_ulines-1)) + 1;
- if(ret_indices[k] >= n_ulines)
- ret_indices[k] = n_ulines-1;
-
-
- ret_innerIndices[k] = (Int)(((tempMaxU-uMin)/(uMax - uMin)) * (n_ulines-1)) + 1;
-
- /*reinitialize tempMaxU for next grdiLine*/
- tempMaxU = uinterc;
- }
-#ifdef SHORTEN_GRID_LINE
- //for each grid line, compare the left grid point with the
- //intersection point. If the two points are too close, then
- //we should move the grid point one grid to the right
- //and accordingly we should update the inner index.
- for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++)
- {
- //check gridLine i
- //check ret_indices[k]
- Real a = grid->get_u_value(ret_indices[k]-1);
- Real b = grid->get_u_value(ret_indices[k]);
- assert(uintercBuf[k] >= a && uintercBuf < b);
- if( (b-uintercBuf[k]) <= 0.2 * (b-a)) //interc is very close to b
- {
- ret_indices[k]++;
- }
-
- //check ret_innerIndices[k]
- if(k>0)
- {
- if(ret_innerIndices[k] < ret_indices[k-1])
- ret_innerIndices[k] = ret_indices[k-1];
- if(ret_innerIndices[k] < ret_indices[k])
- ret_innerIndices[k] = ret_indices[k];
- }
- }
- //clean up
- free(uintercBuf);
-#endif
-}
-
-void findRightGridIndices(directedLine* topEdge, Int firstGridIndex, Int lastGridIndex, gridWrap* grid, Int* ret_indices, Int* ret_innerIndices)
-{
-
- Int i,k;
- Int n_ulines = grid->get_n_ulines();
- Real uMin = grid->get_u_min();
- Real uMax = grid->get_u_max();
- /*
- Real vMin = grid->get_v_min();
- Real vMax = grid->get_v_max();
- */
- Real slop = 0.0, uinterc;
-
-#ifdef SHORTEN_GRID_LINE
- //uintercBuf stores all the interction u value for each grid line
- //notice that firstGridIndex >= lastGridIndex
- Real *uintercBuf = (Real *) malloc (sizeof(Real) * (firstGridIndex-lastGridIndex+1));
- assert(uintercBuf);
-#endif
-
- /*initialization to make vhead bigger than grid->v_value...*/
- directedLine* dLine = topEdge->getPrev();
- Real vhead = dLine->tail()[1];
- Real tempMinU = grid->get_u_max();
-
- /*for each grid line*/
- for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++)
- {
-
- Real grid_v_value = grid->get_v_value(i);
-
-
- /*check whether this grid line is below the current trim edge.*/
- if(vhead >= grid_v_value)
- {
- /*since the grid line is below the tail of the trim edge, we
- *find the trim edge which will contain the trim line
- */
- while( (vhead=dLine->head()[1]) > grid_v_value){
- tempMinU = min(tempMinU, dLine->head()[0]);
- dLine = dLine -> getPrev();
- }
-
- /*skip the equality in the case of degenerat case: horizontal */
- while(dLine->head()[1] == grid_v_value)
- dLine = dLine->getPrev();
-
- assert( dLine->tail()[1] != dLine->head()[1]);
- slop = (dLine->tail()[0] - dLine->head()[0]) / (dLine->tail()[1]-dLine->head()[1]);
- /*
- if(dLine->tail()[1] == vhead)
- isHoriz = 1;
- else
- {
- isHoriz = 0;
- slop = (dLine->tail()[0] - dLine->head()[0]) / (dLine->tail()[1]-vhead);
- }
- */
- }
- uinterc = slop * (grid_v_value - dLine->head()[1]) + dLine->head()[0];
-
- //in case unterc is outside of the grid due to floating point
- if(uinterc < uMin)
- uinterc = uMin;
- else if(uinterc > uMax)
- uinterc = uMax;
-
-#ifdef SHORTEN_GRID_LINE
- uintercBuf[k] = uinterc;
-#endif
-
- tempMinU = min(tempMinU, uinterc);
-
- assert(uinterc >= uMin && uinterc <= uMax);
-
- if(uinterc == uMin)
- ret_indices[k] = 0;
- else
- ret_indices[k] = (int)ceil((((uinterc-uMin)/(uMax - uMin)) * (n_ulines-1))) -1;
-/*
-if(ret_indices[k] >= grid->get_n_ulines())
- {
- printf("ERROR3\n");
- exit(0);
-}
-if(ret_indices[k] < 0)
- {
- printf("ERROR4\n");
- exit(0);
-}
-*/
- ret_innerIndices[k] = (int)ceil ((((tempMinU-uMin)/(uMax - uMin)) * (n_ulines-1))) -1;
-
- tempMinU = uinterc;
- }
-#ifdef SHORTEN_GRID_LINE
- //for each grid line, compare the left grid point with the
- //intersection point. If the two points are too close, then
- //we should move the grid point one grid to the right
- //and accordingly we should update the inner index.
- for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++)
- {
- //check gridLine i
- //check ret_indices[k]
- Real a = grid->get_u_value(ret_indices[k]);
- Real b = grid->get_u_value(ret_indices[k]+1);
- assert(uintercBuf[k] > a && uintercBuf <= b);
- if( (uintercBuf[k]-a) <= 0.2 * (b-a)) //interc is very close to a
- {
- ret_indices[k]--;
- }
-
- //check ret_innerIndices[k]
- if(k>0)
- {
- if(ret_innerIndices[k] > ret_indices[k-1])
- ret_innerIndices[k] = ret_indices[k-1];
- if(ret_innerIndices[k] > ret_indices[k])
- ret_innerIndices[k] = ret_indices[k];
- }
- }
- //clean up
- free(uintercBuf);
-#endif
-}
-
-
-void sampleMonoPoly(directedLine* polygon, gridWrap* grid, Int ulinear, Int vlinear, primStream* pStream, rectBlockArray* rbArray)
-{
-/*
-{
-grid->print();
-polygon->writeAllPolygons("zloutputFile");
-exit(0);
-}
-*/
-
-if(grid->get_n_ulines() == 2 ||
- grid->get_n_vlines() == 2)
-{
- if(ulinear && grid->get_n_ulines() == 2)
- {
- monoTriangulationFun(polygon, compV2InY, pStream);
- return;
- }
- else if(DBG_isConvex(polygon) && polygon->numEdges() >=4)
- {
- triangulateConvexPoly(polygon, ulinear, vlinear, pStream);
- return;
- }
- else if(vlinear || DBG_is_U_direction(polygon))
- {
- Int n_cusps;//num interior cusps
- Int n_edges = polygon->numEdges();
- directedLine** cusps = (directedLine**) malloc(sizeof(directedLine*) * n_edges);
- assert(cusps);
- findInteriorCuspsX(polygon, n_cusps, cusps);
-
- if(n_cusps == 0) //u_monotone
- {
-
- monoTriangulationFun(polygon, compV2InX, pStream);
-
- free(cusps);
- return;
- }
- else if(n_cusps == 1) //one interior cusp
- {
-
- directedLine* new_polygon = polygonConvert(cusps[0]);
-
- directedLine* other = findDiagonal_singleCuspX( new_polygon);
-
-
-
- //<other> should NOT be null unless there are self-intersecting
- //trim curves. In that case, we don't want to core dump, instead,
- //we triangulate anyway, and print out error message.
- if(other == NULL)
- {
- monoTriangulationFun(polygon, compV2InX, pStream);
- free(cusps);
- return;
- }
-
- directedLine* ret_p1;
- directedLine* ret_p2;
-
- new_polygon->connectDiagonal_2slines(new_polygon, other,
- &ret_p1,
- &ret_p2,
- new_polygon);
-
- monoTriangulationFun(ret_p1, compV2InX, pStream);
- monoTriangulationFun(ret_p2, compV2InX, pStream);
-
- ret_p1->deleteSinglePolygonWithSline();
- ret_p2->deleteSinglePolygonWithSline();
-
- free(cusps);
- return;
- }
- free(cusps);
- }
-}
-
- /*find the top and bottom of the polygon. It is supposed to be
- *a V-monotone polygon
- */
-
- directedLine* tempV;
- directedLine* topV;
- directedLine* botV;
- topV = botV = polygon;
-
- for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext())
- {
- if(compV2InY(topV->head(), tempV->head())<0) {
-
- topV = tempV;
- }
- if(compV2InY(botV->head(), tempV->head())>0) {
-
- botV = tempV;
- }
- }
-
- /*find the first(top) and the last (bottom) grid line which intersect the
- *this polygon
- */
- Int firstGridIndex; /*the index in the grid*/
- Int lastGridIndex;
- firstGridIndex = (Int) ((topV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1));
- lastGridIndex = (Int) ((botV->head()[1] - grid->get_v_min()) / (grid->get_v_max() - grid->get_v_min()) * (grid->get_n_vlines()-1)) + 1;
-
-
- /*find the interval inside the polygon for each gridline*/
- Int *leftGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
- assert(leftGridIndices);
- Int *rightGridIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
- assert(rightGridIndices);
- Int *leftGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
- assert(leftGridInnerIndices);
- Int *rightGridInnerIndices = (Int*) malloc(sizeof(Int) * (firstGridIndex - lastGridIndex +1));
- assert(rightGridInnerIndices);
-
- findLeftGridIndices(topV, firstGridIndex, lastGridIndex, grid, leftGridIndices, leftGridInnerIndices);
-
- findRightGridIndices(topV, firstGridIndex, lastGridIndex, grid, rightGridIndices, rightGridInnerIndices);
-
- gridBoundaryChain leftGridChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, leftGridIndices, leftGridInnerIndices);
-
- gridBoundaryChain rightGridChain(grid, firstGridIndex, firstGridIndex-lastGridIndex+1, rightGridIndices, rightGridInnerIndices);
-
-
-
-// leftGridChain.draw();
-// leftGridChain.drawInner();
-// rightGridChain.draw();
-// rightGridChain.drawInner();
- /*(1) determine the grid boundaries (left and right).
- *(2) process polygon into two monotone chaines: use vertexArray
- *(3) call sampleMonoPolyRec
- */
-
- /*copy the two chains into vertexArray datastructure*/
- Int i;
- vertexArray leftChain(20); /*this is a dynamic array*/
- for(i=1; i<=topV->get_npoints()-2; i++) { /*the first vertex is the top vertex which doesn't belong to inc_chain*/
- leftChain.appendVertex(topV->getVertex(i));
- }
- for(tempV = topV->getNext(); tempV != botV; tempV = tempV->getNext())
- {
- for(i=0; i<=tempV->get_npoints()-2; i++){
- leftChain.appendVertex(tempV->getVertex(i));
- }
- }
-
- vertexArray rightChain(20);
- for(tempV = topV->getPrev(); tempV != botV; tempV = tempV->getPrev())
- {
- for(i=tempV->get_npoints()-2; i>=0; i--){
- rightChain.appendVertex(tempV->getVertex(i));
- }
- }
- for(i=botV->get_npoints()-2; i>=1; i--){
- rightChain.appendVertex(tempV->getVertex(i));
- }
-
- sampleMonoPolyRec(topV->head(),
- botV->head(),
- &leftChain,
- 0,
- &rightChain,
- 0,
- &leftGridChain,
- &rightGridChain,
- 0,
- pStream,
- rbArray);
-
-
- /*cleanup space*/
- free(leftGridIndices);
- free(rightGridIndices);
- free(leftGridInnerIndices);
- free(rightGridInnerIndices);
-}
-
-void sampleMonoPolyRec(
- Real* topVertex,
- Real* botVertex,
- vertexArray* leftChain,
- Int leftStartIndex,
- vertexArray* rightChain,
- Int rightStartIndex,
- gridBoundaryChain* leftGridChain,
- gridBoundaryChain* rightGridChain,
- Int gridStartIndex,
- primStream* pStream,
- rectBlockArray* rbArray)
-{
-
- /*find the first connected component, and the four corners.
- */
- Int index1, index2; /*the first and last grid line of the first connected component*/
-
- if(topVertex[1] <= botVertex[1])
- return;
-
- /*find i so that the grid line is below the top vertex*/
- Int i=gridStartIndex;
- while (i < leftGridChain->get_nVlines())
- {
- if(leftGridChain->get_v_value(i) < topVertex[1])
- break;
- i++;
- }
-
- /*find the first connected component starting with i*/
- /*find index1 so that left_uline_index <= right_uline_index, that is, this
- *grid line contains at least one inner grid point
- */
- index1=i;
- int num_skipped_grid_lines=0;
- while(index1 < leftGridChain->get_nVlines())
- {
- if(leftGridChain->getUlineIndex(index1) <= rightGridChain->getUlineIndex(index1))
- break;
- num_skipped_grid_lines++;
- index1++;
- }
-
-
-
- if(index1 >= leftGridChain->get_nVlines()) /*no grid line exists which has inner point*/
- {
- /*stop recursion, ...*/
- /*monotone triangulate it...*/
-// printf("no grid line exists\n");
-/*
- monoTriangulationRecOpt(topVertex, botVertex, leftChain, leftStartIndex,
- rightChain, rightStartIndex, pStream);
-*/
-
-if(num_skipped_grid_lines <2)
- {
- monoTriangulationRecGenOpt(topVertex, botVertex, leftChain, leftStartIndex,
- leftChain->getNumElements()-1,
- rightChain, rightStartIndex,
- rightChain->getNumElements()-1,
- pStream);
- }
-else
- {
- //the optimum way to triangulate is top-down since this polygon
- //is narrow-long.
- monoTriangulationRec(topVertex, botVertex, leftChain, leftStartIndex,
- rightChain, rightStartIndex, pStream);
- }
-
-/*
- monoTriangulationRec(topVertex, botVertex, leftChain, leftStartIndex,
- rightChain, rightStartIndex, pStream);
-*/
-
-/* monoTriangulationRecGenTBOpt(topVertex, botVertex,
- leftChain, leftStartIndex, leftChain->getNumElements()-1,
- rightChain, rightStartIndex, rightChain->getNumElements()-1,
- pStream);*/
-
-
-
- }
- else
- {
-
- /*find index2 so that left_inner_index <= right_inner_index holds until index2*/
- index2=index1+1;
- if(index2 < leftGridChain->get_nVlines())
- while(leftGridChain->getInnerIndex(index2) <= rightGridChain->getInnerIndex(index2))
- {
- index2++;
- if(index2 >= leftGridChain->get_nVlines())
- break;
- }
-
- index2--;
-
-
-
- /*the neck*/
- Int neckLeftIndex;
- Int neckRightIndex;
-
- /*the four corners*/
- Int up_leftCornerWhere;
- Int up_leftCornerIndex;
- Int up_rightCornerWhere;
- Int up_rightCornerIndex;
- Int down_leftCornerWhere;
- Int down_leftCornerIndex;
- Int down_rightCornerWhere;
- Int down_rightCornerIndex;
-
- Real* tempBotVertex; /*the bottom vertex for this component*/
- Real* nextTopVertex=NULL; /*for the recursion*/
- Int nextLeftStartIndex=0;
- Int nextRightStartIndex=0;
-
- /*find the points below the grid line index2 on both chains*/
- Int botLeftIndex = leftChain->findIndexStrictBelowGen(
- leftGridChain->get_v_value(index2),
- leftStartIndex,
- leftChain->getNumElements()-1);
- Int botRightIndex = rightChain->findIndexStrictBelowGen(
- rightGridChain->get_v_value(index2),
- rightStartIndex,
- rightChain->getNumElements()-1);
- /*if either botLeftIndex>= numelements,
- * or botRightIndex >= numelemnet,
- *then there is no neck exists. the bottom vertex is botVertex,
- */
- if(! findNeckF(leftChain, botLeftIndex, rightChain, botRightIndex,
- leftGridChain, rightGridChain, index2, neckLeftIndex, neckRightIndex))
- /*
- if(botLeftIndex == leftChain->getNumElements() ||
- botRightIndex == rightChain->getNumElements())
- */
- {
-#ifdef MYDEBUG
- printf("neck NOT exists, botRightIndex=%i\n", botRightIndex);
-#endif
-
- tempBotVertex = botVertex;
- nextTopVertex = botVertex;
- botLeftIndex = leftChain->getNumElements()-1;
- botRightIndex = rightChain->getNumElements()-1;
- }
- else /*neck exists*/
- {
-#ifdef MYDEBUG
- printf("neck exists\n");
-#endif
-
- /*
- findNeck(leftChain, botLeftIndex,
- rightChain, botRightIndex,
- neckLeftIndex,
- neckRightIndex);
- */
-#ifdef MYDEBUG
-printf("neck is found, neckLeftIndex=%i, neckRightIndex=%i\n", neckLeftIndex, neckRightIndex);
-glBegin(GL_LINES);
-glVertex2fv(leftChain->getVertex(neckLeftIndex));
-glVertex2fv(rightChain->getVertex(neckRightIndex));
-glEnd();
-#endif
-
- if(leftChain->getVertex(neckLeftIndex)[1] <= rightChain->getVertex(neckRightIndex)[1])
- {
- tempBotVertex = leftChain->getVertex(neckLeftIndex);
- botLeftIndex = neckLeftIndex-1;
- botRightIndex = neckRightIndex;
- nextTopVertex = rightChain->getVertex(neckRightIndex);
- nextLeftStartIndex = neckLeftIndex;
- nextRightStartIndex = neckRightIndex+1;
- }
- else
- {
- tempBotVertex = rightChain->getVertex(neckRightIndex);
- botLeftIndex = neckLeftIndex;
- botRightIndex = neckRightIndex-1;
- nextTopVertex = leftChain->getVertex(neckLeftIndex);
- nextLeftStartIndex = neckLeftIndex+1;
- nextRightStartIndex = neckRightIndex;
- }
- }
-
- findUpCorners(topVertex,
- leftChain,
- leftStartIndex, botLeftIndex,
- rightChain,
- rightStartIndex, botRightIndex,
- leftGridChain->get_v_value(index1),
- leftGridChain->get_u_value(index1),
- rightGridChain->get_u_value(index1),
- up_leftCornerWhere,
- up_leftCornerIndex,
- up_rightCornerWhere,
- up_rightCornerIndex);
-
- findDownCorners(tempBotVertex,
- leftChain,
- leftStartIndex, botLeftIndex,
- rightChain,
- rightStartIndex, botRightIndex,
- leftGridChain->get_v_value(index2),
- leftGridChain->get_u_value(index2),
- rightGridChain->get_u_value(index2),
- down_leftCornerWhere,
- down_leftCornerIndex,
- down_rightCornerWhere,
- down_rightCornerIndex);
-#ifdef MYDEBUG
- printf("find corners done, down_leftwhere=%i, down_righwhere=%i,\n",down_leftCornerWhere, down_rightCornerWhere );
- printf("find corners done, up_leftwhere=%i, up_righwhere=%i,\n",up_leftCornerWhere, up_rightCornerWhere );
- printf("find corners done, up_leftindex=%i, up_righindex=%i,\n",up_leftCornerIndex, up_rightCornerIndex );
- printf("find corners done, down_leftindex=%i, down_righindex=%i,\n",down_leftCornerIndex, down_rightCornerIndex );
-#endif
-
-/*
- drawCorners(topVertex,
- tempBotVertex,
- leftChain,
- rightChain,
- leftGridChain,
- rightGridChain,
- index1,
- index2,
- up_leftCornerWhere,
- up_leftCornerIndex,
- up_rightCornerWhere,
- up_rightCornerIndex,
- down_leftCornerWhere,
- down_leftCornerIndex,
- down_rightCornerWhere,
- down_rightCornerIndex);
-*/
-
-
- sampleConnectedComp(topVertex, tempBotVertex,
- leftChain,
- leftStartIndex, botLeftIndex,
- rightChain,
- rightStartIndex, botRightIndex,
- leftGridChain,
- rightGridChain,
- index1, index2,
- up_leftCornerWhere,
- up_leftCornerIndex,
- up_rightCornerWhere,
- up_rightCornerIndex,
- down_leftCornerWhere,
- down_leftCornerIndex,
- down_rightCornerWhere,
- down_rightCornerIndex,
- pStream,
- rbArray
- );
-
- /*recursion*/
-
- sampleMonoPolyRec(
- nextTopVertex,
- botVertex,
- leftChain,
- nextLeftStartIndex,
- rightChain,
- nextRightStartIndex,
- leftGridChain,
- rightGridChain,
- index2+1,
- pStream, rbArray);
-
-
- }
-
-}
-
-void sampleLeftStrip(vertexArray* leftChain,
- Int topLeftIndex,
- Int botLeftIndex,
- gridBoundaryChain* leftGridChain,
- Int leftGridChainStartIndex,
- Int leftGridChainEndIndex,
- primStream* pStream
- )
-{
- assert(leftChain->getVertex(topLeftIndex)[1] > leftGridChain->get_v_value(leftGridChainStartIndex));
- assert(leftChain->getVertex(topLeftIndex+1)[1] <= leftGridChain->get_v_value(leftGridChainStartIndex));
- assert(leftChain->getVertex(botLeftIndex)[1] <= leftGridChain->get_v_value(leftGridChainEndIndex));
- assert(leftChain->getVertex(botLeftIndex-1)[1] > leftGridChain->get_v_value(leftGridChainEndIndex));
-
- /*
- *(1)find the last grid line which doesn'; pass below
- * this first edge, sample this region: one trim edge and
- * possily multiple grid lines.
- */
- Real *upperVert, *lowerVert; /*the end points of the first trim edge*/
- upperVert = leftChain->getVertex(topLeftIndex);
- lowerVert = leftChain->getVertex(topLeftIndex+1);
-
- Int index = leftGridChainStartIndex;
- while(leftGridChain->get_v_value(index) >= lowerVert[1]){
- index++;
- if(index > leftGridChainEndIndex)
- break;
- }
- index--;
-
- sampleLeftSingleTrimEdgeRegion(upperVert, lowerVert,
- leftGridChain,
- leftGridChainStartIndex,
- index,
- pStream);
- sampleLeftStripRec(leftChain, topLeftIndex+1, botLeftIndex,
- leftGridChain, index, leftGridChainEndIndex,
- pStream);
-
-}
-
-void sampleLeftStripRec(vertexArray* leftChain,
- Int topLeftIndex,
- Int botLeftIndex,
- gridBoundaryChain* leftGridChain,
- Int leftGridChainStartIndex,
- Int leftGridChainEndIndex,
- primStream* pStream
- )
-{
- /*now top left trim vertex is below the top grid line.
- */
- /*stop condition: if topLeftIndex >= botLeftIndex, then stop.
- */
- if(topLeftIndex >= botLeftIndex)
- return;
-
- /*find the last trim vertex which is above the second top grid line:
- * index1.
- *and sampleLeftOneGridStep(leftchain, topLeftIndex, index1, leftGridChain,
- * leftGridChainStartIndex).
- * index1 could be equal to topLeftIndex.
- */
- Real secondGridChainV = leftGridChain->get_v_value(leftGridChainStartIndex+1);
- assert(leftGridChainStartIndex < leftGridChainEndIndex);
- Int index1 = topLeftIndex;
- while(leftChain->getVertex(index1)[1] > secondGridChainV)
- index1++;
- index1--;
-
- sampleLeftOneGridStep(leftChain, topLeftIndex, index1, leftGridChain, leftGridChainStartIndex, pStream);
-
-
- /*
- * Let the next trim vertex be nextTrimVertIndex (which should be
- * below the second grid line).
- * Find the last grid line index2 which is above nextTrimVert.
- * sampleLeftSingleTrimEdgeRegion(uppervert[2], lowervert[2],
- * leftGridChain, leftGridChainStartIndex+1, index2).
- */
- Real *uppervert, *lowervert;
- uppervert = leftChain->getVertex(index1);
- lowervert = leftChain->getVertex(index1+1);
- Int index2 = leftGridChainStartIndex+1;
-
- while(leftGridChain->get_v_value(index2) >= lowervert[1])
- {
- index2++;
- if(index2 > leftGridChainEndIndex)
- break;
- }
- index2--;
- sampleLeftSingleTrimEdgeRegion(uppervert, lowervert, leftGridChain, leftGridChainStartIndex+1, index2, pStream);
-
- /* sampleLeftStripRec(leftChain,
- nextTrimVertIndex,
- botLeftIndex,
- leftGridChain,
- index2,
- leftGridChainEndIndex
- )
- *
- */
- sampleLeftStripRec(leftChain, index1+1, botLeftIndex, leftGridChain, index2, leftGridChainEndIndex, pStream);
-
-}
-
-
-/***************begin RecF***********************/
-/* the gridlines from leftGridChainStartIndex to
- * leftGridChainEndIndex are assumed to form a
- * connected component.
- * the trim vertex of topLeftIndex is assumed to
- * be below the first gridline, and the tim vertex
- * of botLeftIndex is assumed to be above the last
- * grid line.
- * If botLeftIndex < topLeftIndex, then no connected componeent exists, and this funcion returns without
- * outputing any triangles.
- * Otherwise botLeftIndex >= topLeftIndex, there is at least one triangle to output.
- */
-void sampleLeftStripRecF(vertexArray* leftChain,
- Int topLeftIndex,
- Int botLeftIndex,
- gridBoundaryChain* leftGridChain,
- Int leftGridChainStartIndex,
- Int leftGridChainEndIndex,
- primStream* pStream
- )
-{
- /*now top left trim vertex is below the top grid line.
- */
- /*stop condition: if topLeftIndex > botLeftIndex, then stop.
- */
- if(topLeftIndex > botLeftIndex)
- return;
-
- /*if there is only one grid Line, return.*/
-
- if(leftGridChainStartIndex>=leftGridChainEndIndex)
- return;
-
-
- assert(leftChain->getVertex(topLeftIndex)[1] <= leftGridChain->get_v_value(leftGridChainStartIndex) &&
- leftChain->getVertex(botLeftIndex)[1] >= leftGridChain->get_v_value(leftGridChainEndIndex));
-
- /*firs find the first trim vertex which is below or equal to the second top grid line:
- * index1.
- */
- Real secondGridChainV = leftGridChain->get_v_value(leftGridChainStartIndex+1);
-
-
- Int index1 = topLeftIndex;
-
- while(leftChain->getVertex(index1)[1] > secondGridChainV){
- index1++;
- if(index1>botLeftIndex)
- break;
- }
-
- /*now leftChain->getVertex(index-1)[1] > secondGridChainV and
- * leftChain->getVertex(index)[1] <= secondGridChainV
- *If equality holds, then we should include the vertex index1, otherwise we include only index1-1, to
- *perform sampleOneGridStep.
- */
- if(index1>botLeftIndex)
- index1--;
- else if(leftChain->getVertex(index1)[1] < secondGridChainV)
- index1--;
-
- /*now we have leftChain->getVertex(index1)[1] >= secondGridChainV, and
- * leftChain->getVertex(index1+1)[1] <= secondGridChainV
- */
-
-
- sampleLeftOneGridStep(leftChain, topLeftIndex, index1, leftGridChain, leftGridChainStartIndex, pStream);
-
-
- /*if leftChain->getVertex(index1)[1] == secondGridChainV, then we can recursively do the rest.
- */
- if(leftChain->getVertex(index1)[1] == secondGridChainV)
- {
-
- sampleLeftStripRecF(leftChain, index1, botLeftIndex,leftGridChain, leftGridChainStartIndex+1, leftGridChainEndIndex, pStream);
- }
- else if(index1 < botLeftIndex)
- {
-
- /* Otherwise, we have leftChain->getVertex(index1)[1] > secondGridChainV,
- * let the next trim vertex be nextTrimVertIndex (which should be strictly
- * below the second grid line).
- * Find the last grid line index2 which is above nextTrimVert.
- * sampleLeftSingleTrimEdgeRegion(uppervert[2], lowervert[2],
- * leftGridChain, leftGridChainStartIndex+1, index2).
- */
- Real *uppervert, *lowervert;
- uppervert = leftChain->getVertex(index1);
- lowervert = leftChain->getVertex(index1+1); //okay since index1<botLeftIndex
- Int index2 = leftGridChainStartIndex+1;
-
-
- while(leftGridChain->get_v_value(index2) >= lowervert[1])
- {
- index2++;
- if(index2 > leftGridChainEndIndex)
- break;
- }
- index2--;
-
-
- sampleLeftSingleTrimEdgeRegion(uppervert, lowervert, leftGridChain, leftGridChainStartIndex+1, index2, pStream);
-
- /*recursion*/
-
- sampleLeftStripRecF(leftChain, index1+1, botLeftIndex, leftGridChain, index2, leftGridChainEndIndex, pStream);
- }
-
-}
-
-/***************End RecF***********************/
-
-/*sample the left area in between one trim edge and multiple grid lines.
- * all the grid lines should be in between the two end poins of the
- *trim edge.
- */
-void sampleLeftSingleTrimEdgeRegion(Real upperVert[2], Real lowerVert[2],
- gridBoundaryChain* gridChain,
- Int beginIndex,
- Int endIndex,
- primStream* pStream)
-{
- Int i,j,k;
-
- vertexArray vArray(endIndex-beginIndex+1);
- vArray.appendVertex(gridChain->get_vertex(beginIndex));
-
- for(k=1, i=beginIndex+1; i<=endIndex; i++, k++)
- {
- vArray.appendVertex(gridChain->get_vertex(i));
-
- /*output the fan of the grid points of the (i)th and (i-1)th grid line.
- */
- if(gridChain->getUlineIndex(i) < gridChain->getUlineIndex(i-1))
- {
- pStream->begin();
- pStream->insert(gridChain->get_vertex(i-1));
- for(j=gridChain->getUlineIndex(i); j<= gridChain->getUlineIndex(i-1); j++)
- pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i));
- pStream->end(PRIMITIVE_STREAM_FAN);
- }
- else if(gridChain->getUlineIndex(i) > gridChain->getUlineIndex(i-1))
- {
- pStream->begin();
- pStream->insert(gridChain->get_vertex(i));
- for(j=gridChain->getUlineIndex(i); j>= gridChain->getUlineIndex(i-1); j--)
- pStream->insert(gridChain->getGrid()->get_u_value(j), gridChain->get_v_value(i-1));
- pStream->end(PRIMITIVE_STREAM_FAN);
- }
- /*otherwisem, the two are equal, so there is no fan to outout*/
- }
-
- monoTriangulation2(upperVert, lowerVert, &vArray, 0, endIndex-beginIndex,
- 0, /*decreasing chain*/
- pStream);
-}
-
-/*return i, such that from begin to i-1 the chain is strictly u-monotone.
- */
-Int findIncreaseChainFromBegin(vertexArray* chain, Int begin ,Int end)
-{
- Int i=begin;
- Real prevU = chain->getVertex(i)[0];
- Real thisU;
- for(i=begin+1; i<=end; i++){
- thisU = chain->getVertex(i)[0];
-
- if(prevU < thisU){
- prevU = thisU;
- }
- else
- break;
- }
- return i;
-}
-
-/*check whether there is a vertex whose v value is strictly
- *inbetween vup vbelow
- *if no middle exists return -1, else return the idnex.
- */
-Int checkMiddle(vertexArray* chain, Int begin, Int end,
- Real vup, Real vbelow)
-{
- Int i;
- for(i=begin; i<=end; i++)
- {
- if(chain->getVertex(i)[1] < vup && chain->getVertex(i)[1]>vbelow)
- return i;
- }
- return -1;
-}
-
-/*the degenerat case of sampleLeftOneGridStep*/
-void sampleLeftOneGridStepNoMiddle(vertexArray* leftChain,
- Int beginLeftIndex,
- Int endLeftIndex,
- gridBoundaryChain* leftGridChain,
- Int leftGridChainStartIndex,
- primStream* pStream)
-{
- /*since there is no middle, there is at most one point which is on the
- *second grid line, there could be multiple points on the first (top)
- *grid line.
- */
-
- leftGridChain->leftEndFan(leftGridChainStartIndex+1, pStream);
-
- monoTriangulation2(leftGridChain->get_vertex(leftGridChainStartIndex),
- leftGridChain->get_vertex(leftGridChainStartIndex+1),
- leftChain,
- beginLeftIndex,
- endLeftIndex,
- 1, //is increase chain.
- pStream);
-}
-
-
-
-/*sampling the left area in between two grid lines.
- */
-void sampleLeftOneGridStep(vertexArray* leftChain,
- Int beginLeftIndex,
- Int endLeftIndex,
- gridBoundaryChain* leftGridChain,
- Int leftGridChainStartIndex,
- primStream* pStream
- )
-{
- if(checkMiddle(leftChain, beginLeftIndex, endLeftIndex,
- leftGridChain->get_v_value(leftGridChainStartIndex),
- leftGridChain->get_v_value(leftGridChainStartIndex+1))<0)
-
- {
-
- sampleLeftOneGridStepNoMiddle(leftChain, beginLeftIndex, endLeftIndex, leftGridChain, leftGridChainStartIndex, pStream);
- return;
- }
-
- //copy into a polygon
- {
- directedLine* poly = NULL;
- sampledLine* sline;
- directedLine* dline;
- gridWrap* grid = leftGridChain->getGrid();
- Real vert1[2];
- Real vert2[2];
- Int i;
-
- Int innerInd = leftGridChain->getInnerIndex(leftGridChainStartIndex+1);
- Int upperInd = leftGridChain->getUlineIndex(leftGridChainStartIndex);
- Int lowerInd = leftGridChain->getUlineIndex(leftGridChainStartIndex+1);
- Real upperV = leftGridChain->get_v_value(leftGridChainStartIndex);
- Real lowerV = leftGridChain->get_v_value(leftGridChainStartIndex+1);
-
- //the upper gridline
- vert1[1] = vert2[1] = upperV;
- for(i=innerInd; i>upperInd; i--)
- {
- vert1[0]=grid->get_u_value(i);
- vert2[0]=grid->get_u_value(i-1);
- sline = new sampledLine(vert1, vert2);
- dline = new directedLine(INCREASING, sline);
- if(poly == NULL)
- poly = dline;
- else
- poly->insert(dline);
- }
-
- //the edge connecting upper grid with left chain
- vert1[0] = grid->get_u_value(upperInd);
- vert1[1] = upperV;
- sline = new sampledLine(vert1, leftChain->getVertex(beginLeftIndex));
- dline = new directedLine(INCREASING, sline);
- if(poly == NULL)
- poly = dline;
- else
- poly->insert(dline);
-
- //the left chain
- for(i=beginLeftIndex; i<endLeftIndex; i++)
- {
- sline = new sampledLine(leftChain->getVertex(i), leftChain->getVertex(i+1));
- dline = new directedLine(INCREASING, sline);
- poly->insert(dline);
- }
-
- //the edge connecting left chain with lower gridline
- vert2[0] = grid->get_u_value(lowerInd);
- vert2[1] = lowerV;
- sline = new sampledLine(leftChain->getVertex(endLeftIndex), vert2);
- dline = new directedLine(INCREASING, sline);
- poly->insert(dline);
-
- //the lower grid line
- vert1[1] = vert2[1] = lowerV;
- for(i=lowerInd; i<innerInd; i++)
- {
- vert1[0] = grid->get_u_value(i);
- vert2[0] = grid->get_u_value(i+1);
- sline = new sampledLine(vert1, vert2);
- dline = new directedLine(INCREASING, sline);
- poly->insert(dline);
- }
-
- //the vertical grid line segement
- vert1[0]=vert2[0] = grid->get_u_value(innerInd);
- vert2[1]=upperV;
- vert1[1]=lowerV;
- sline=new sampledLine(vert1, vert2);
- dline=new directedLine(INCREASING, sline);
- poly->insert(dline);
- monoTriangulationOpt(poly, pStream);
- //cleanup
- poly->deleteSinglePolygonWithSline();
- return;
- }
-
-
-
-
-
- Int i;
- if(1/*leftGridChain->getUlineIndex(leftGridChainStartIndex) >=
- leftGridChain->getUlineIndex(leftGridChainStartIndex+1)*/
- ) /*the second grid line is beyond the first one to the left*/
- {
- /*find the maximal U-monotone chain
- * of endLeftIndex, endLeftIndex-1, ...,
- */
- i=endLeftIndex;
- Real prevU = leftChain->getVertex(i)[0];
- for(i=endLeftIndex-1; i>=beginLeftIndex; i--){
- Real thisU = leftChain->getVertex(i)[0];
- if( prevU < thisU){
- prevU = thisU;
- }
- else
- break;
- }
- /*from endLeftIndex to i+1 is strictly U- monotone */
- /*if i+1==endLeftIndex and the vertex and leftchain is on the second gridline, then
- *we should use 2 vertices on the leftchain. If we only use one (endLeftIndex), then we
- *we would output degenerate triangles
- */
- if(i+1 == endLeftIndex && leftChain->getVertex(endLeftIndex)[1] == leftGridChain->get_v_value(1+leftGridChainStartIndex))
- i--;
-
- Int j = beginLeftIndex/*endLeftIndex*/+1;
-
-
- if(leftGridChain->getInnerIndex(leftGridChainStartIndex+1) > leftGridChain->getUlineIndex(leftGridChainStartIndex))
- {
- j = findIncreaseChainFromBegin(leftChain, beginLeftIndex, i+1/*endLeftIndex*/);
-
- Int temp = beginLeftIndex;
- /*now from begin to j-1 is strictly u-monotone*/
- /*if j-1 is on the first grid line, then we want to skip to the vertex which is strictly
- *below the grid line. This vertexmust exist since there is a 'corner turn' inbetween the two grid lines
- */
- if(j-1 == beginLeftIndex)
- {
- while(leftChain->getVertex(j-1)[1] == leftGridChain->get_v_value(leftGridChainStartIndex))
- j++;
-
- Real vert[2];
- vert[0] = leftGridChain->get_u_value(leftGridChainStartIndex);
- vert[1] = leftGridChain->get_v_value(leftGridChainStartIndex);
-
- monoTriangulation2(
- vert/*leftChain->getVertex(beginLeftIndex)*/,
- leftChain->getVertex(j-1),
- leftChain,
- beginLeftIndex,
- j-2,
- 1,
- pStream //increase chain
- );
-
- temp = j-1;
- }
-
- stripOfFanLeft(leftChain, j-1, temp/*beginLeftIndex*/, leftGridChain->getGrid(),
- leftGridChain->getVlineIndex(leftGridChainStartIndex),
- leftGridChain->getUlineIndex(leftGridChainStartIndex),
- leftGridChain->getInnerIndex(leftGridChainStartIndex+1),
- pStream,
- 1 /*the grid line is above the trim line*/
- );
- }
-
- stripOfFanLeft(leftChain, endLeftIndex, i+1, leftGridChain->getGrid(),
- leftGridChain->getVlineIndex(leftGridChainStartIndex+1),
- leftGridChain->getUlineIndex(leftGridChainStartIndex+1),
- leftGridChain->getInnerIndex(leftGridChainStartIndex+1),
- pStream,
- 0 /*the grid line is below the trim lines*/
- );
-
- /*monotone triangulate the remaining left chain togther with the
- *two vertices on the two grid v-lines.
- */
- Real vert[2][2];
- vert[0][0]=vert[1][0] = leftGridChain->getInner_u_value(leftGridChainStartIndex+1);
- vert[0][1] = leftGridChain->get_v_value(leftGridChainStartIndex);
- vert[1][1] = leftGridChain->get_v_value(leftGridChainStartIndex+1);
-
-// vertexArray right(vert, 2);
-
- monoTriangulation2(
- &vert[0][0], /*top vertex */
- &vert[1][0], /*bottom vertex*/
- leftChain,
- /*beginLeftIndex*/j-1,
- i+1,
- 1, /*an increasing chain*/
- pStream);
- }
- else /*the second one is shorter than the first one to the left*/
- {
- /*find the maximal U-monotone chain of beginLeftIndex, beginLeftIndex+1,...,
- */
- i=beginLeftIndex;
- Real prevU = leftChain->getVertex(i)[0];
- for(i=beginLeftIndex+1; i<=endLeftIndex; i++){
- Real thisU = leftChain->getVertex(i)[0];
-
- if(prevU < thisU){
- prevU = thisU;
- }
- else
- break;
- }
- /*from beginLeftIndex to i-1 is strictly U-monotone*/
-
-
- stripOfFanLeft(leftChain, i-1, beginLeftIndex, leftGridChain->getGrid(),
- leftGridChain->getVlineIndex(leftGridChainStartIndex),
- leftGridChain->getUlineIndex(leftGridChainStartIndex),
- leftGridChain->getUlineIndex(leftGridChainStartIndex+1),
- pStream,
- 1 /*the grid line is above the trim lines*/
- );
- /*monotone triangulate the remaining left chain together with the
- *two vertices on the two grid v-lines.
- */
- Real vert[2][2];
- vert[0][0]=vert[1][0] = leftGridChain->get_u_value(leftGridChainStartIndex+1);
- vert[0][1] = leftGridChain->get_v_value(leftGridChainStartIndex);
- vert[1][1] = leftGridChain->get_v_value(leftGridChainStartIndex+1);
-
- vertexArray right(vert, 2);
-
- monoTriangulation2(
- &vert[0][0], //top vertex
- &vert[1][0], //bottom vertex
- leftChain,
- i-1,
- endLeftIndex,
- 1, /*an increase chain*/
- pStream);
-
- }
-}
-
-/*n_upper>=1
- *n_lower>=1
- */
-void triangulateXYMono(Int n_upper, Real upperVerts[][2],
- Int n_lower, Real lowerVerts[][2],
- primStream* pStream)
-{
- Int i,j,k,l;
- Real* leftMostV;
-
- assert(n_upper>=1 && n_lower>=1);
- if(upperVerts[0][0] <= lowerVerts[0][0])
- {
- i=1;
- j=0;
- leftMostV = upperVerts[0];
- }
- else
- {
- i=0;
- j=1;
- leftMostV = lowerVerts[0];
- }
-
- while(1)
- {
- if(i >= n_upper) /*case1: no more in upper*/
- {
-
- if(j<n_lower-1) /*at least two vertices in lower*/
- {
- pStream->begin();
- pStream->insert(leftMostV);
- while(j<n_lower){
- pStream->insert(lowerVerts[j]);
- j++;
- }
- pStream->end(PRIMITIVE_STREAM_FAN);
- }
-
- break;
- }
- else if(j>= n_lower) /*case2: no more in lower*/
- {
-
- if(i<n_upper-1) /*at least two vertices in upper*/
- {
- pStream->begin();
- pStream->insert(leftMostV);
-
- for(k=n_upper-1; k>=i; k--)
- pStream->insert(upperVerts[k]);
-
- pStream->end(PRIMITIVE_STREAM_FAN);
- }
-
- break;
- }
- else /* case3: neither is empty, plus the leftMostV, there is at least one triangle to output*/
- {
-
- if(upperVerts[i][0] <= lowerVerts[j][0])
- {
- pStream->begin();
- pStream->insert(lowerVerts[j]); /*the origin of this fan*/
-
- /*find the last k>=i such that
- *upperverts[k][0] <= lowerverts[j][0]
- */
- k=i;
- while(k<n_upper)
- {
- if(upperVerts[k][0] > lowerVerts[j][0])
- break;
- k++;
- }
- k--;
- for(l=k; l>=i; l--)/*the reverse is for two-face lighting*/
- {
- pStream->insert(upperVerts[l]);
- }
- pStream->insert(leftMostV);
-
- pStream->end(PRIMITIVE_STREAM_FAN);
- //update i for next loop
- i = k+1;
- leftMostV = upperVerts[k];
-
- }
- else /*upperVerts[i][0] > lowerVerts[j][0]*/
- {
- pStream->begin();
- pStream->insert(upperVerts[i]);/*the origion of this fan*/
- pStream->insert(leftMostV);
- /*find the last k>=j such that
- *lowerverts[k][0] < upperverts[i][0]*/
- k=j;
- while(k< n_lower)
- {
- if(lowerVerts[k][0] >= upperVerts[i][0])
- break;
- pStream->insert(lowerVerts[k]);
- k++;
- }
- pStream->end(PRIMITIVE_STREAM_FAN);
- j=k;
- leftMostV = lowerVerts[j-1];
- }
- }
- }
-}
-
-
-void stripOfFanLeft(vertexArray* leftChain,
- Int largeIndex,
- Int smallIndex,
- gridWrap* grid,
- Int vlineIndex,
- Int ulineSmallIndex,
- Int ulineLargeIndex,
- primStream* pStream,
- Int gridLineUp /*1 if the grid line is above the trim lines*/
- )
-{
- assert(largeIndex >= smallIndex);
-
- Real grid_v_value;
- grid_v_value = grid->get_v_value(vlineIndex);
-
- Real2* trimVerts=(Real2*) malloc(sizeof(Real2)* (largeIndex-smallIndex+1));
- assert(trimVerts);
-
-
- Real2* gridVerts=(Real2*) malloc(sizeof(Real2)* (ulineLargeIndex-ulineSmallIndex+1));
- assert(gridVerts);
-
- Int k,i;
- if(gridLineUp) /*trim line is below grid line, so trim vertices are going right when index increases*/
- for(k=0, i=smallIndex; i<=largeIndex; i++, k++)
- {
- trimVerts[k][0] = leftChain->getVertex(i)[0];
- trimVerts[k][1] = leftChain->getVertex(i)[1];
- }
- else
- for(k=0, i=largeIndex; i>=smallIndex; i--, k++)
- {
- trimVerts[k][0] = leftChain->getVertex(i)[0];
- trimVerts[k][1] = leftChain->getVertex(i)[1];
- }
-
- for(k=0, i=ulineSmallIndex; i<= ulineLargeIndex; i++, k++)
- {
- gridVerts[k][0] = grid->get_u_value(i);
- gridVerts[k][1] = grid_v_value;
- }
-
- if(gridLineUp)
- triangulateXYMono(
- ulineLargeIndex-ulineSmallIndex+1, gridVerts,
- largeIndex-smallIndex+1, trimVerts,
- pStream);
- else
- triangulateXYMono(largeIndex-smallIndex+1, trimVerts,
- ulineLargeIndex-ulineSmallIndex+1, gridVerts,
- pStream);
- free(trimVerts);
- free(gridVerts);
-}
-
-
-
-
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-#ifndef _SAMPLEMONOPOLY_H
-#define _SAMPLEMONOPOLY_H
-
-#include "monoTriangulation.h"
-#include "gridWrap.h"
-#include "rectBlock.h"
-
-
-void triangulateXYMono(Int n_upper, Real upperVerts[][2],
- Int n_lower, Real lowerVerts[][2],
- primStream* pStream);
-
-void stripOfFanLeft(vertexArray* leftChain,
- Int largeIndex,
- Int smallIndex,
- gridWrap* grid,
- Int vlineIndex,
- Int ulineSmallIndex,
- Int ulineLargeIndex,
- primStream* pStream,
- Int gridLineUp
- );
-void sampleLeftOneGridStep(vertexArray* leftChain,
- Int beginLeftIndex,
- Int endLeftIndex,
- gridBoundaryChain* leftGridChain,
- Int leftGridChainStartIndex,
- primStream* pStream
- );
-
-void sampleLeftSingleTrimEdgeRegion(Real upperVert[2], Real lowerVert[2],
- gridBoundaryChain* gridChain,
- Int beginIndex,
- Int endIndex,
- primStream* pStream);
-
-void sampleLeftStripRec(vertexArray* leftChain,
- Int topLeftIndex,
- Int botLeftIndex,
- gridBoundaryChain* leftGridChain,
- Int leftGridChainStartIndex,
- Int leftGridChainEndIndex,
- primStream* pStream
- );
-
-void sampleLeftStrip(vertexArray* leftChain,
- Int topLeftIndex,
- Int botLeftIndex,
- gridBoundaryChain* leftGridChain,
- Int leftGridChainStartIndex,
- Int leftGridChainEndIndex,
- primStream* pStream
- );
-
-void findLeftGridIndices(directedLine* topEdge, Int firstGridIndex, Int lastGridIndex, gridWrap* grid, Int* ret_indices, Int* ret_inner);
-
-void findRightGridIndices(directedLine* topEdge, Int firstGridIndex, Int lastGridIndex, gridWrap* grid, Int* ret_indices, Int* ret_inner);
-
-void sampleMonoPoly(directedLine* polygon, gridWrap* grid, Int ulinear, Int vlinear, primStream *pStream, rectBlockArray* rbArray);
-
-void sampleMonoPolyRec(
- Real* topVertex,
- Real* botVertex,
- vertexArray* leftChain,
- Int leftStartIndex,
- vertexArray* rightChain,
- Int rightStartIndex,
- gridBoundaryChain* leftGridChain,
- gridBoundaryChain* rightGridChain,
- Int gridStartIndex,
- primStream* pStream,
- rectBlockArray* rbArray
- );
-
-void sampleLeftStripRecF(vertexArray* leftChain,
- Int topLeftIndex,
- Int botLeftIndex,
- gridBoundaryChain* leftGridChain,
- Int leftGridChainStartIndex,
- Int leftGridChainEndIndex,
- primStream* pStream
- );
-
-void findUpCorners(Real *topVertex,
- vertexArray *leftChain,
- Int leftChainStartIndex, Int leftChainEndIndex,
- vertexArray *rightChain,
- Int rightChainStartIndex, Int rightChainEndIndex,
- Real v,
- Real uleft,
- Real uright,
- Int& ret_leftCornerWhere,
- Int& ret_leftCornerIndex,
- Int& ret_rightCornerWhere,
- Int& ret_rightCornerIndex
- );
-void findDownCorners(Real *botVertex,
- vertexArray *leftChain, Int leftChainStartIndex, Int leftChainEndIndex,
- vertexArray *rightChain, Int rightChainStartIndex, Int rightChainEndIndex,
- Real v,
- Real uleft,
- Real uright,
- Int& ret_leftCornerWhere,
- Int& ret_leftCornerIndex,
- Int& ret_rightCornerWhere,
- Int& ret_rightCornerIndex
- );
-void findNeck(vertexArray *leftChain, Int botLeftIndex,
- vertexArray *rightChain, Int botRightIndex,
- Int& leftLastIndex, /*left point of the neck*/
- Int& rightLastIndex /*right point of the neck*/
- );
-
-Int findNeckF(vertexArray *leftChain, Int botLeftIndex,
- vertexArray *rightChain, Int botRightIndex,
- gridBoundaryChain* leftGridChain,
- gridBoundaryChain* rightGridChain,
- Int gridStartIndex,
- Int& neckLeft,
- Int& neckRight);
-
-void findTopAndBot(directedLine* polygon,
- directedLine*& topV,
- directedLine*& botV);
-void findGridChains(directedLine* top, directedLine* bot,
- gridWrap* grid,
- gridBoundaryChain*& leftGridChain,
- gridBoundaryChain*& rightGridChain);
-void toVertexArrays(directedLine* topV, directedLine* botV, vertexArray& leftChain, vertexArray& rightChain);
-
-void drawCorners(
- Real* topV, Real* botV,
- vertexArray* leftChain,
- vertexArray* rightChain,
- gridBoundaryChain* leftGridChain,
- gridBoundaryChain* rightGridChain,
- Int gridIndex1,
- Int gridIndex2,
- Int leftCornerWhere,
- Int leftCornerIndex,
- Int rightCornerWhere,
- Int rightCornerIndex,
- Int bot_leftCornerWhere,
- Int bot_leftCornerIndex,
- Int bot_rightCornerWhere,
- Int bot_rightCornerIndex);
-
-Int checkMiddle(vertexArray* chain, Int begin, Int end,
- Real vup, Real vbelow);
-
-#endif
-
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h> //for fabs()
-#include "glimports.h"
-#include "zlassert.h"
-#include "sampledLine.h"
-
-void sampledLine::setPoint(Int i, Real p[2])
-{
- points[i][0]=p[0];
- points[i][1]=p[1];
-}
-
-
-/*insert this single line in front of the oldList*/
-sampledLine* sampledLine::insert(sampledLine *oldList)
-{
- next = oldList;
- return this;
-}
-
-void sampledLine::deleteList()
-{
- sampledLine *temp, *tempNext;
- for(temp = this; temp != NULL; temp = tempNext)
- {
- tempNext = temp->next;
- delete temp;
- }
-}
-
-
-/*space of points[][2] is allocated*/
-sampledLine::sampledLine(Int n_points)
-{
- npoints = n_points;
- points = (Real2*) malloc(sizeof(Real2) * n_points);
- assert(points);
- next = NULL;
-}
-
-/*space of points[][2] is allocated and
- *points are copied
- */
-sampledLine::sampledLine(Int n_points, Real2 pts[])
-{
- int i;
- npoints = n_points;
- points = (Real2*) malloc(sizeof(Real2) * n_points);
- assert(points);
- for(i=0; i<npoints; i++) {
- points[i][0] = pts[i][0];
- points[i][1] = pts[i][1];
- }
- next = NULL;
-}
-
-sampledLine::sampledLine(Real pt1[2], Real pt2[2])
-{
- npoints = 2;
- points = (Real2*) malloc(sizeof(Real2) * 2);
- assert(points);
- points[0][0] = pt1[0];
- points[0][1] = pt1[1];
- points[1][0] = pt2[0];
- points[1][1] = pt2[1];
- next = NULL;
-}
-
-//needs tp call init to setup
-sampledLine::sampledLine()
-{
- npoints = 0;
- points = NULL;
- next = NULL;
-}
-
-//warning: ONLY pointer is copies!!!
-void sampledLine::init(Int n_points, Real2 *pts)
-{
- npoints = n_points;
- points = pts;
-}
-
-/*points[] is dealocated
- */
-sampledLine::~sampledLine()
-{
- free(points);
-}
-
-void sampledLine::print()
-{
- int i;
- printf("npoints=%i\n", npoints);
-
- for(i=0; i<npoints; i++){
- printf("(%f,%f)\n", points[i][0], points[i][1]);
- }
-
-}
-
-void sampledLine::tessellate(Real u_reso, Real v_reso)
-{
- int i;
-
- Int nu, nv, n;
- nu = 1+(Int) (fabs((points[npoints-1][0] - points[0][0])) * u_reso);
- nv = 1+(Int) (fabs((points[npoints-1][1] - points[0][1])) * v_reso);
-
- if(nu > nv) n = nu;
- else
- n = nv;
- if(n<1)
- n = 1;
- //du dv could be negative
- Real du = (points[npoints-1][0] - points[0][0])/n;
- Real dv = (points[npoints-1][1] - points[0][1])/n;
- Real2 *temp = (Real2*) malloc(sizeof(Real2) * (n+1));
- assert(temp);
-
- Real u,v;
- for(i=0, u=points[0][0], v=points[0][1]; i<n; i++, u+=du, v+=dv)
- {
- temp[i][0] = u;
- temp[i][1] = v;
- }
- temp[n][0] = points[npoints-1][0];
- temp[n][1] = points[npoints-1][1];
-
- free(points);
-
- npoints = n+1;
- points = temp;
-
-}
-
-void sampledLine::tessellateAll(Real u_reso, Real v_reso)
-{
- sampledLine* temp;
- for(temp = this; temp != NULL; temp = temp->next)
- {
- temp->tessellate(u_reso, v_reso);
- }
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-#ifndef _SAMPLEDLINE_H
-#define _SAMPLEDLINE_H
-
-#include "definitions.h"
-
-class sampledLine{
- Int npoints;
- Real2 *points;
-
-public:
- sampledLine(Int n_points);
- sampledLine(Int n_points, Real pts[][2]);
- sampledLine(Real pt1[2], Real pt2[2]);
- sampledLine(); //special, careful about memory
- ~sampledLine();
-
- void init(Int n_points, Real2 *pts);//special, careful about memory
-
- void setPoint(Int i, Real p[2]) ;
-
- sampledLine* insert(sampledLine *nline);
- void deleteList();
-
- Int get_npoints() {return npoints;}
- Real2* get_points() {return points;}
-
- //u_reso is number of segments (may not be integer) per unit u
- void tessellate(Real u_reso, Real v_reso);//n segments
- void tessellateAll(Real u_reso, Real v_reso);
-
- void print();
-
- sampledLine* next;
-};
-
-
-
-
-#endif
+++ /dev/null
-/*
-** 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.
-**
-*/
-/*
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include "zlassert.h"
-
-#include "searchTree.h"
-
-#define max(a,b) ((a>b)? a:b)
-
-treeNode* TreeNodeMake(void *key)
-{
- treeNode *ret = (treeNode*) malloc(sizeof(treeNode));
- assert(ret);
- ret->key = key;
- ret->parent = NULL;
- ret->left = NULL;
- ret->right = NULL;
- return ret;
-}
-
-void TreeNodeDeleteSingleNode(treeNode* node)
-{
- free(node);
-}
-
-void TreeNodeDeleteWholeTree(treeNode* node)
-{
- if(node == NULL) return;
- TreeNodeDeleteWholeTree(node->left);
- TreeNodeDeleteWholeTree(node->right);
- TreeNodeDeleteSingleNode(node);
-}
-
-void TreeNodePrint(treeNode* node,
- void (*keyPrint) (void*))
-{
- if(node ==NULL) return;
- TreeNodePrint(node->left, keyPrint);
- keyPrint(node->key);
- TreeNodePrint(node->right, keyPrint);
-}
-
-int TreeNodeDepth(treeNode* root)
-{
- if(root == NULL) return 0;
- else{
- int leftdepth = TreeNodeDepth(root->left);
- int rightdepth = TreeNodeDepth(root->right);
- return 1 + max(leftdepth, rightdepth);
- }
-}
-
-/*return the node with the key.
- *NULL is returned if not found
- */
-treeNode* TreeNodeFind(treeNode* tree, void* key,
- int (*compkey) (void*, void*))
-{
- if(tree == NULL)
- return NULL;
- if(key == tree->key)
- return tree;
- else if(compkey(key, tree->key) < 0)
- return TreeNodeFind(tree->left, key, compkey);
- else
- return TreeNodeFind(tree->right, key, compkey);
-}
-
-
-treeNode* TreeNodeInsert(treeNode* root, treeNode* newnode,
- int (*compkey) (void *, void *))
-{
- treeNode *y = NULL;
- treeNode *x = root;
- /*going down the tree from the root.
- *x traces the path, y is the parent of x.
- */
- while (x != NULL){
- y = x;
- if(compkey(newnode->key,x->key) < 0) /*if newnode < x*/
- x = x->left;
- else
- x = x->right;
- }
-
- /*now y has the property that
- * if newnode < y, then y->left is NULL
- * if newnode > y, then y->right is NULL.
- *So we want to isnert newnode to be the child of y
- */
- newnode->parent = y;
- if(y == NULL)
- return newnode;
- else if( compkey(newnode->key, y->key) <0)
- {
- y->left = newnode;
- }
- else
- {
- y->right = newnode;
- }
-
- return root;
-}
-
-treeNode* TreeNodeDeleteSingleNode(treeNode* tree, treeNode* node)
-{
- treeNode* y;
- treeNode* x;
- treeNode* ret;
- if(node==NULL) return tree;
-
- if(node->left == NULL || node->right == NULL) {
-
- y = node;
- if(y->left != NULL)
- x = y->left;
- else
- x = y->right;
-
- if( x != NULL)
- x->parent = y->parent;
-
- if(y->parent == NULL) /*y is the root which has at most one child x*/
- ret = x;
- else /*y is not the root*/
- {
- if(y == y->parent->left)
- y->parent->left = x;
- else
- y->parent->right = x;
- ret = tree;
- }
- }
- else { /*node has two children*/
-
- y = TreeNodeSuccessor(node);
- assert(y->left == NULL);
-
- if(y == node->right) /*y is the right child if node*/
- {
- y->parent = node->parent;
- y->left = node->left;
- node->left->parent = y;
-
- }
- else /*y != node->right*/
- {
- x = y->right;
- if(x!= NULL)
- x->parent = y->parent;
-
- assert(y->parent != NULL);
- if(y == y->parent->left)
- y->parent->left = x;
- else
- y->parent->right = x;
- /*move y to the position of node*/
- y->parent = node->parent;
- y->left = node->left;
- y->right = node->right;
- node->left->parent = y;
- node->right->parent = y;
- }
- if(node->parent != NULL) {
- if(node->parent->left == node)
- node->parent->left = y;
- else
- node->parent->right = y;
- ret = tree; /*the root if the tree doesn't change*/
- }
- else /*node->parent is NULL: node is the root*/
- ret = y;
- }
-
- /*finally free the node, and return the new root*/
- TreeNodeDeleteSingleNode(node);
- return ret;
-}
-
-
-/*the minimum node in the tree rooted by node
- */
-treeNode* TreeNodeMinimum(treeNode* node)
-{
- treeNode* temp = node;
- if(temp == NULL) return NULL;
- while(temp->left != NULL) {
- temp = temp->left;
- }
- return temp;
-}
-
-/*the maximum node in the tree rooted by node
- */
-treeNode* TreeNodeMaximum(treeNode* node)
-{
- treeNode* temp = node;
- if(temp == NULL) return NULL;
- while(temp->right != NULL) {
- temp = temp->right;
- }
- return temp;
-}
-
-/*return the first node (in sorted order) which is to the right of this node
- */
-treeNode* TreeNodeSuccessor(treeNode* node)
-{
- if(node == NULL) return NULL;
- if(node->right != NULL)
- return TreeNodeMinimum(node->right);
- else{ /*node->right is NULL*/
-
- /*find the first right-ancestor*/
- treeNode *y = node->parent;
- treeNode* x = node;
- while(y != NULL && x == y->right) /*if y is a left parent of x*/
- {
-
- x = y;
- y = y->parent;
- }
- return y;
- }
-}
-
-/*return the first node (in sorted order) which is to the left of this node
- */
-treeNode* TreeNodePredecessor(treeNode* node)
-{
- if(node == NULL) return NULL;
- if(node->left != NULL)
- return TreeNodeMaximum(node->left);
- else{ /*node->left is NULL*/
- /*find the first left-ancestor*/
- treeNode *y = node->parent;
- treeNode *x = node;
- while(y != NULL && x == y->left) /*if y is a right parent of x*/
- {
- x = y;
- y = y->parent;
- }
- return y;
- }
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-#ifndef _SEARCHTREE_H
-#define _SEARCHTREE_H
-
-typedef struct treeNode{
- void *key;
- struct treeNode* parent;
- struct treeNode* left; /*children*/
- struct treeNode* right;
-} treeNode;
-
-treeNode* TreeNodeMake(void *key);
-void TreeNodeDeleteSingleNode(treeNode* node);
-void TreeNodeDeleteWholeTree(treeNode* node);
-void TreeNodePrint(treeNode* node,
- void (*keyPrint) (void*));
-int TreeNodeDepth(treeNode* root);
-treeNode* TreeNodeMinimum(treeNode* node);
-treeNode* TreeNodeMaximum(treeNode* node);
-treeNode* TreeNodePredecessor(treeNode* node);
-treeNode* TreeNodeSuccessor(treeNode* node);
-treeNode* TreeNodeFind(treeNode* tree, void* key,
- int (*compkey) (void*, void*));
-
-treeNode* TreeNodeInsert(treeNode* root, treeNode* newnode,
- int (*comp) (void *, void *));
-treeNode* TreeNodeDeleteSingleNode(treeNode* tree, treeNode* node);
-
-
-#endif
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-*/
-
-/*XXXblythe this file should be deleted*/
-#include <assert.h>
+++ /dev/null
-/*
-*/
-
-General Polygon Tesselation
----------------------------
-
- This note describes a tesselator for polygons consisting of one or
- more closed contours. It is backward-compatible with the current
- OpenGL Utilities tesselator, and is intended to replace it. Here is
- a summary of the major differences:
-
- - input contours can be intersecting, self-intersecting, or degenerate.
-
- - supports a choice of several winding rules for determining which parts
- of the polygon are on the "interior". This makes it possible to do
- CSG operations on polygons.
-
- - boundary extraction: instead of tesselating the polygon, returns a
- set of closed contours which separate the interior from the exterior.
-
- - returns the output as a small number of triangle fans and strips,
- rather than a list of independent triangles (when possible).
-
- - output is available as an explicit mesh (a quad-edge structure),
- in addition to the normal callback interface.
-
- - the algorithm used is extremely robust.
-
-
-The interface
--------------
-
- The tesselator state is maintained in a "tesselator object".
- These are allocated and destroyed using
-
- GLUtesselator *gluNewTess( void );
- void gluDeleteTess( GLUtesselator *tess );
-
- Several tesselator objects may be used simultaneously.
-
- Inputs
- ------
-
- The input contours are specified with the following routines:
-
- void gluTessBeginPolygon( GLUtesselator *tess );
- void gluTessBeginContour( GLUtesselator *tess );
- void gluTessVertex( GLUtesselator *tess, GLUcoord coords[3], void *data );
- void gluTessEndContour( GLUtesselator *tess );
- void gluTessEndPolygon( GLUtesselator *tess );
-
- Within each BeginPolygon/EndPolygon pair, there can be zero or more
- calls to BeginContour/EndContour. Within each contour, there are zero
- or more calls to gluTessVertex(). The vertices specify a closed
- contour (the last vertex of each contour is automatically linked to
- the first).
-
- "coords" give the coordinates of the vertex in 3-space. For useful
- results, all vertices should lie in some plane, since the vertices
- are projected onto a plane before tesselation. "data" is a pointer
- to a user-defined vertex structure, which typically contains other
- information such as color, texture coordinates, normal, etc. It is
- used to refer to the vertex during rendering.
-
- The library can be compiled in single- or double-precision; the type
- GLUcoord represents either "float" or "double" accordingly. The GLU
- version will be available in double-precision only. Compile with
- GLU_TESS_API_FLOAT defined to get the single-precision version.
-
- When EndPolygon is called, the tesselation algorithm determines
- which regions are interior to the given contours, according to one
- of several "winding rules" described below. The interior regions
- are then tesselated, and the output is provided as callbacks.
-
-
- Rendering Callbacks
- -------------------
-
- Callbacks are specified by the client using
-
- void gluTessCallback( GLUtesselator *tess, GLenum which, void (*fn)());
-
- If "fn" is NULL, any previously defined callback is discarded.
-
- The callbacks used to provide output are: /* which == */
-
- void begin( GLenum type ); /* GLU_TESS_BEGIN */
- void edgeFlag( GLboolean flag ); /* GLU_TESS_EDGE_FLAG */
- void vertex( void *data ); /* GLU_TESS_VERTEX */
- void end( void ); /* GLU_TESS_END */
-
- Any of the callbacks may be left undefined; if so, the corresponding
- information will not be supplied during rendering.
-
- The "begin" callback indicates the start of a primitive; type is one
- of GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, or GL_TRIANGLES (but see the
- notes on "boundary extraction" below).
-
- It is followed by any number of "vertex" callbacks, which supply the
- vertices in the same order as expected by the corresponding glBegin()
- call. After the last vertex of a given primitive, there is a callback
- to "end".
-
- If the "edgeFlag" callback is provided, no triangle fans or strips
- will be used. When edgeFlag is called, if "flag" is GL_TRUE then each
- vertex which follows begins an edge which lies on the polygon boundary
- (ie. an edge which separates an interior region from an exterior one).
- If "flag" is GL_FALSE, each vertex which follows begins an edge which lies
- in the polygon interior. "edgeFlag" will be called before the first
- call to "vertex".
-
- Other Callbacks
- ---------------
-
- void mesh( GLUmesh *mesh ); /* GLU_TESS_MESH */
-
- - Returns an explicit mesh, represented using the quad-edge structure
- (Guibas/Stolfi '85). Other implementations of this interface might
- use a different mesh structure, so this is available only only as an
- SGI extension. When the mesh is no longer needed, it should be freed
- using
-
- void gluDeleteMesh( GLUmesh *mesh );
-
- There is a brief description of this data structure in the include
- file "mesh.h". For the full details, see L. Guibas and J. Stolfi,
- Primitives for the manipulation of general subdivisions and the
- computation of Voronoi diagrams, ACM Transactions on Graphics,
- 4(2):74-123, April 1985. For an introduction, see the course notes
- for CS348a, "Mathematical Foundations of Computer Graphics",
- available at the Stanford bookstore (and taught during the fall
- quarter).
-
- void error( GLenum errno ); /* GLU_TESS_ERROR */
-
- - errno is one of GLU_TESS_MISSING_BEGIN_POLYGON,
- GLU_TESS_MISSING_END_POLYGON,
- GLU_TESS_MISSING_BEGIN_CONTOUR,
- GLU_TESS_MISSING_END_CONTOUR,
- GLU_TESS_COORD_TOO_LARGE,
- GLU_TESS_NEED_COMBINE_CALLBACK
-
- The first four are obvious. The interface recovers from these
- errors by inserting the missing call(s).
-
- GLU_TESS_COORD_TOO_LARGE says that some vertex coordinate exceeded
- the predefined constant GLU_TESS_MAX_COORD in absolute value, and
- that the value has been clamped. (Coordinate values must be small
- enough so that two can be multiplied together without overflow.)
-
- GLU_TESS_NEED_COMBINE_CALLBACK says that the algorithm detected an
- intersection between two edges in the input data, and the "combine"
- callback (below) was not provided. No output will be generated.
-
-
- void combine( GLUcoord coords[3], void *data[4], /* GLU_TESS_COMBINE */
- GLUcoord weight[4], void **outData );
-
- - When the algorithm detects an intersection, or wishes to merge
- features, it needs to create a new vertex. The vertex is defined
- as a linear combination of up to 4 existing vertices, referenced
- by data[0..3]. The coefficients of the linear combination are
- given by weight[0..3]; these weights always sum to 1.0. All vertex
- pointers are valid even when some of the weights are zero.
- "coords" gives the location of the new vertex.
-
- The user must allocate another vertex, interpolate parameters
- using "data" and "weights", and return the new vertex pointer in
- "outData". This handle is supplied during rendering callbacks.
- For example, if the polygon lies in an arbitrary plane in 3-space,
- and we associate a color with each vertex, the combine callback might
- look like this:
-
- void myCombine( GLUcoord coords[3], VERTEX *d[4],
- GLUcoord w[4], VERTEX **dataOut )
- {
- VERTEX *new = new_vertex();
-
- new->x = coords[0];
- new->y = coords[1];
- new->z = coords[2];
- new->r = w[0]*d[0]->r + w[1]*d[1]->r + w[2]*d[2]->r + w[3]*d[3]->r;
- new->g = w[0]*d[0]->g + w[1]*d[1]->g + w[2]*d[2]->g + w[3]*d[3]->g;
- new->b = w[0]*d[0]->b + w[1]*d[1]->b + w[2]*d[2]->b + w[3]*d[3]->b;
- new->a = w[0]*d[0]->a + w[1]*d[1]->a + w[2]*d[2]->a + w[3]*d[3]->a;
- *dataOut = new;
- }
-
- If the algorithm detects an intersection, then the "combine" callback
- must be defined, and must write a non-NULL pointer into "dataOut".
- Otherwise the GLU_TESS_NEED_COMBINE_CALLBACK error occurs, and no
- output is generated. This is the only error that can occur during
- tesselation and rendering.
-
-
- Control over Tesselation
- ------------------------
-
- void gluTessProperty( GLUtesselator *tess, GLenum which, GLUcoord value );
-
- Properties defined:
-
- - GLU_TESS_WINDING_RULE. Possible values:
-
- GLU_TESS_WINDING_ODD
- GLU_TESS_WINDING_NONZERO
- GLU_TESS_WINDING_POSITIVE
- GLU_TESS_WINDING_NEGATIVE
- GLU_TESS_WINDING_ABS_GEQ_TWO
-
- The input contours parition the plane into regions. A winding
- rule determines which of these regions are inside the polygon.
-
- For a single contour C, the winding number of a point x is simply
- the signed number of revolutions we make around x as we travel
- once around C (where CCW is positive). When there are several
- contours, the individual winding numbers are summed. This
- procedure associates a signed integer value with each point x in
- the plane. Note that the winding number is the same for all
- points in a single region.
-
- The winding rule classifies a region as "inside" if its winding
- number belongs to the chosen category (odd, nonzero, positive,
- negative, or absolute value of at least two). The current GLU
- tesselator implements the "odd" rule. The "nonzero" rule is another
- common way to define the interior. The other three rules are
- useful for polygon CSG operations (see below).
-
- - GLU_TESS_BOUNDARY_ONLY. Values: TRUE (non-zero) or FALSE (zero).
-
- If TRUE, returns a set of closed contours which separate the
- polygon interior and exterior (rather than a tesselation).
- Exterior contours are oriented CCW with respect to the normal,
- interior contours are oriented CW. The GLU_TESS_BEGIN callback
- uses the type GL_LINE_LOOP for each contour.
-
- - GLU_TESS_TOLERANCE. Value: a real number between 0.0 and 1.0.
-
- This specifies a tolerance for merging features to reduce the size
- of the output. For example, two vertices which are very close to
- each other might be replaced by a single vertex. The tolerance
- is multiplied by the largest coordinate magnitude of any input vertex;
- this specifies the maximum distance that any feature can move as the
- result of a single merge operation. If a single feature takes part
- in several merge operations, the total distance moved could be larger.
-
- Feature merging is completely optional; the tolerance is only a hint.
- The implementation is free to merge in some cases and not in others,
- or to never merge features at all. The default tolerance is zero.
-
- The current implementation merges vertices only if they are exactly
- coincident, regardless of the current tolerance. A vertex is
- spliced into an edge only if the implementation is unable to
- distinguish which side of the edge the vertex lies on.
- Two edges are merged only when both endpoints are identical.
-
-
- void gluTessNormal( GLUtesselator *tess,
- GLUcoord x, GLUcoord y, GLUcoord z )
-
- - Lets the user supply the polygon normal, if known. All input data
- is projected into a plane perpendicular to the normal before
- tesselation. All output triangles are oriented CCW with
- respect to the normal (CW orientation can be obtained by
- reversing the sign of the supplied normal). For example, if
- you know that all polygons lie in the x-y plane, call
- "gluTessNormal(tess, 0.0, 0.0, 1.0)" before rendering any polygons.
-
- - If the supplied normal is (0,0,0) (the default value), the
- normal is determined as follows. The direction of the normal,
- up to its sign, is found by fitting a plane to the vertices,
- without regard to how the vertices are connected. It is
- expected that the input data lies approximately in plane;
- otherwise projection perpendicular to the computed normal may
- substantially change the geometry. The sign of the normal is
- chosen so that the sum of the signed areas of all input contours
- is non-negative (where a CCW contour has positive area).
-
- - The supplied normal persists until it is changed by another
- call to gluTessNormal.
-
-
- Backward compatibility with the GLU tesselator
- ----------------------------------------------
-
- The preferred interface is the one described above. The following
- routines are obsolete, and are provided only for backward compatibility:
-
- typedef GLUtesselator GLUtriangulatorObj; /* obsolete name */
-
- void gluBeginPolygon( GLUtesselator *tess );
- void gluNextContour( GLUtesselator *tess, GLenum type );
- void gluEndPolygon( GLUtesselator *tess );
-
- "type" is one of GLU_EXTERIOR, GLU_INTERIOR, GLU_CCW, GLU_CW, or
- GLU_UNKNOWN. It is ignored by the current GLU tesselator.
-
- GLU_BEGIN, GLU_VERTEX, GLU_END, GLU_ERROR, and GLU_EDGE_FLAG are defined
- as synonyms for GLU_TESS_BEGIN, GLU_TESS_VERTEX, GLU_TESS_END,
- GLU_TESS_ERROR, and GLU_TESS_EDGE_FLAG.
-
-
-Polygon CSG operations
-----------------------
-
- The features of the tesselator make it easy to find the union, difference,
- or intersection of several polygons.
-
- First, assume that each polygon is defined so that the winding number
- is 0 for each exterior region, and 1 for each interior region. Under
- this model, CCW contours define the outer boundary of the polygon, and
- CW contours define holes. Contours may be nested, but a nested
- contour must be oriented oppositely from the contour that contains it.
-
- If the original polygons do not satisfy this description, they can be
- converted to this form by first running the tesselator with the
- GLU_TESS_BOUNDARY_ONLY property turned on. This returns a list of
- contours satisfying the restriction above. By allocating two
- tesselator objects, the callbacks from one tesselator can be fed
- directly to the input of another.
-
- Given two or more polygons of the form above, CSG operations can be
- implemented as follows:
-
- Union
- Draw all the input contours as a single polygon. The winding number
- of each resulting region is the number of original polygons
- which cover it. The union can be extracted using the
- GLU_TESS_WINDING_NONZERO or GLU_TESS_WINDING_POSITIVE winding rules.
- Note that with the nonzero rule, we would get the same result if
- all contour orientations were reversed.
-
- Intersection (two polygons at a time only)
- Draw a single polygon using the contours from both input polygons.
- Extract the result using GLU_TESS_WINDING_ABS_GEQ_TWO. (Since this
- winding rule looks at the absolute value, reversing all contour
- orientations does not change the result.)
-
- Difference
-
- Suppose we want to compute A \ (B union C union D). Draw a single
- polygon consisting of the unmodified contours from A, followed by
- the contours of B,C,D with the vertex order reversed (this changes
- the winding number of the interior regions to -1). To extract the
- result, use the GLU_TESS_WINDING_POSITIVE rule.
-
- If B,C,D are the result of a GLU_TESS_BOUNDARY_ONLY call, an
- alternative to reversing the vertex order is to reverse the sign of
- the supplied normal. For example in the x-y plane, call
- gluTessNormal( tess, 0.0, 0.0, -1.0 ).
-
-
-Performance
------------
-
- The tesselator is not intended for immediate-mode rendering; when
- possible the output should be cached in a user structure or display
- list. General polygon tesselation is an inherently difficult problem,
- especially given the goal of extreme robustness.
-
- The implementation makes an effort to output a small number of fans
- and strips; this should improve the rendering performance when the
- output is used in a display list.
-
- Single-contour input polygons are first tested to see whether they can
- be rendered as a triangle fan with respect to the first vertex (to
- avoid running the full decomposition algorithm on convex polygons).
- Non-convex polygons may be rendered by this "fast path" as well, if
- the algorithm gets lucky in its choice of a starting vertex.
-
- For best performance follow these guidelines:
-
- - supply the polygon normal, if available, using gluTessNormal().
- This represents about 10% of the computation time. For example,
- if all polygons lie in the x-y plane, use gluTessNormal(tess,0,0,1).
-
- - render many polygons using the same tesselator object, rather than
- allocating a new tesselator for each one. (In a multi-threaded,
- multi-processor environment you may get better performance using
- several tesselators.)
-
-
-Comparison with the GLU tesselator
-----------------------------------
-
- On polygons which make it through the "fast path", the tesselator is
- 3 to 5 times faster than the GLU tesselator.
-
- On polygons which don't make it through the fast path (but which don't
- have self-intersections or degeneracies), it is about 2 times slower.
-
- On polygons with self-intersections or degeneraces, there is nothing
- to compare against.
-
- The new tesselator generates many more fans and strips, reducing the
- number of vertices that need to be sent to the hardware.
-
- Key to the statistics:
-
- vert number of input vertices on all contours
- cntr number of input contours
- tri number of triangles in all output primitives
- strip number of triangle strips
- fan number of triangle fans
- ind number of independent triangles
- ms number of milliseconds for tesselation
- (on a 150MHz R4400 Indy)
-
- Convex polygon examples:
-
-New: 3 vert, 1 cntr, 1 tri, 0 strip, 0 fan, 1 ind, 0.0459 ms
-Old: 3 vert, 1 cntr, 1 tri, 0 strip, 0 fan, 1 ind, 0.149 ms
-New: 4 vert, 1 cntr, 2 tri, 0 strip, 1 fan, 0 ind, 0.0459 ms
-Old: 4 vert, 1 cntr, 2 tri, 0 strip, 0 fan, 2 ind, 0.161 ms
-New: 36 vert, 1 cntr, 34 tri, 0 strip, 1 fan, 0 ind, 0.153 ms
-Old: 36 vert, 1 cntr, 34 tri, 0 strip, 0 fan, 34 ind, 0.621 ms
-
- Concave single-contour polygons:
-
-New: 5 vert, 1 cntr, 3 tri, 0 strip, 1 fan, 0 ind, 0.052 ms
-Old: 5 vert, 1 cntr, 3 tri, 0 strip, 0 fan, 3 ind, 0.252 ms
-New: 19 vert, 1 cntr, 17 tri, 2 strip, 2 fan, 1 ind, 0.911 ms
-Old: 19 vert, 1 cntr, 17 tri, 0 strip, 0 fan, 17 ind, 0.529 ms
-New: 151 vert, 1 cntr, 149 tri, 13 strip, 18 fan, 3 ind, 6.82 ms
-Old: 151 vert, 1 cntr, 149 tri, 0 strip, 3 fan, 143 ind, 2.7 ms
-New: 574 vert, 1 cntr, 572 tri, 59 strip, 54 fan, 11 ind, 26.6 ms
-Old: 574 vert, 1 cntr, 572 tri, 0 strip, 31 fan, 499 ind, 12.4 ms
-
- Multiple contours, but no intersections:
-
-New: 7 vert, 2 cntr, 7 tri, 1 strip, 0 fan, 0 ind, 0.527 ms
-Old: 7 vert, 2 cntr, 7 tri, 0 strip, 0 fan, 7 ind, 0.274 ms
-New: 81 vert, 6 cntr, 89 tri, 9 strip, 7 fan, 6 ind, 3.88 ms
-Old: 81 vert, 6 cntr, 89 tri, 0 strip, 13 fan, 61 ind, 2.2 ms
-New: 391 vert, 19 cntr, 413 tri, 37 strip, 32 fan, 26 ind, 20.2 ms
-Old: 391 vert, 19 cntr, 413 tri, 0 strip, 25 fan, 363 ind, 8.68 ms
-
- Self-intersecting and degenerate examples:
-
-Bowtie: 4 vert, 1 cntr, 2 tri, 0 strip, 0 fan, 2 ind, 0.483 ms
-Star: 5 vert, 1 cntr, 5 tri, 0 strip, 0 fan, 5 ind, 0.91 ms
-Random: 24 vert, 7 cntr, 46 tri, 2 strip, 12 fan, 7 ind, 5.32 ms
-Font: 333 vert, 2 cntr, 331 tri, 32 strip, 16 fan, 3 ind, 14.1 ms
-: 167 vert, 35 cntr, 254 tri, 8 strip, 56 fan, 52 ind, 46.3 ms
-: 78 vert, 1 cntr, 2675 tri, 148 strip, 207 fan, 180 ind, 243 ms
-: 12480 vert, 2 cntr, 12478 tri, 736 strip,1275 fan, 5 ind, 1010 ms
+++ /dev/null
-/*
-*/
-
-This is only a very brief overview. There is quite a bit of
-additional documentation in the source code itself.
-
-
-Goals of robust tesselation
----------------------------
-
-The tesselation algorithm is fundamentally a 2D algorithm. We
-initially project all data into a plane; our goal is to robustly
-tesselate the projected data. The same topological tesselation is
-then applied to the input data.
-
-Topologically, the output should always be a tesselation. If the
-input is even slightly non-planar, then some triangles will
-necessarily be back-facing when viewed from some angles, but the goal
-is to minimize this effect.
-
-The algorithm needs some capability of cleaning up the input data as
-well as the numerical errors in its own calculations. One way to do
-this is to specify a tolerance as defined above, and clean up the
-input and output during the line sweep process. At the very least,
-the algorithm must handle coincident vertices, vertices incident to an
-edge, and coincident edges.
-
-
-Phases of the algorithm
------------------------
-
-1. Find the polygon normal N.
-2. Project the vertex data onto a plane. It does not need to be
- perpendicular to the normal, eg. we can project onto the plane
- perpendicular to the coordinate axis whose dot product with N
- is largest.
-3. Using a line-sweep algorithm, partition the plane into x-monotone
- regions. Any vertical line intersects an x-monotone region in
- at most one interval.
-4. Triangulate the x-monotone regions.
-5. Group the triangles into strips and fans.
-
-
-Finding the normal vector
--------------------------
-
-A common way to find a polygon normal is to compute the signed area
-when the polygon is projected along the three coordinate axes. We
-can't do this, since contours can have zero area without being
-degenerate (eg. a bowtie).
-
-We fit a plane to the vertex data, ignoring how they are connected
-into contours. Ideally this would be a least-squares fit; however for
-our purpose the accuracy of the normal is not important. Instead we
-find three vertices which are widely separated, and compute the normal
-to the triangle they form. The vertices are chosen so that the
-triangle has an area at least 1/sqrt(3) times the largest area of any
-triangle formed using the input vertices.
-
-The contours do affect the orientation of the normal; after computing
-the normal, we check that the sum of the signed contour areas is
-non-negative, and reverse the normal if necessary.
-
-
-Projecting the vertices
------------------------
-
-We project the vertices onto a plane perpendicular to one of the three
-coordinate axes. This helps numerical accuracy by removing a
-transformation step between the original input data and the data
-processed by the algorithm. The projection also compresses the input
-data; the 2D distance between vertices after projection may be smaller
-than the original 2D distance. However by choosing the coordinate
-axis whose dot product with the normal is greatest, the compression
-factor is at most 1/sqrt(3).
-
-Even though the *accuracy* of the normal is not that important (since
-we are projecting perpendicular to a coordinate axis anyway), the
-*robustness* of the computation is important. For example, if there
-are many vertices which lie almost along a line, and one vertex V
-which is well-separated from the line, then our normal computation
-should involve V otherwise the results will be garbage.
-
-The advantage of projecting perpendicular to the polygon normal is
-that computed intersection points will be as close as possible to
-their ideal locations. To get this behavior, define TRUE_PROJECT.
-
-
-The Line Sweep
---------------
-
-There are three data structures: the mesh, the event queue, and the
-edge dictionary.
-
-The mesh is a "quad-edge" data structure which records the topology of
-the current decomposition; for details see the include file "mesh.h".
-
-The event queue simply holds all vertices (both original and computed
-ones), organized so that we can quickly extract the vertex with the
-minimum x-coord (and among those, the one with the minimum y-coord).
-
-The edge dictionary describes the current intersection of the sweep
-line with the regions of the polygon. This is just an ordering of the
-edges which intersect the sweep line, sorted by their current order of
-intersection. For each pair of edges, we store some information about
-the monotone region between them -- these are call "active regions"
-(since they are crossed by the current sweep line).
-
-The basic algorithm is to sweep from left to right, processing each
-vertex. The processed portion of the mesh (left of the sweep line) is
-a planar decomposition. As we cross each vertex, we update the mesh
-and the edge dictionary, then we check any newly adjacent pairs of
-edges to see if they intersect.
-
-A vertex can have any number of edges. Vertices with many edges can
-be created as vertices are merged and intersection points are
-computed. For unprocessed vertices (right of the sweep line), these
-edges are in no particular order around the vertex; for processed
-vertices, the topological ordering should match the geometric ordering.
-
-The vertex processing happens in two phases: first we process are the
-left-going edges (all these edges are currently in the edge
-dictionary). This involves:
-
- - deleting the left-going edges from the dictionary;
- - relinking the mesh if necessary, so that the order of these edges around
- the event vertex matches the order in the dictionary;
- - marking any terminated regions (regions which lie between two left-going
- edges) as either "inside" or "outside" according to their winding number.
-
-When there are no left-going edges, and the event vertex is in an
-"interior" region, we need to add an edge (to split the region into
-monotone pieces). To do this we simply join the event vertex to the
-rightmost left endpoint of the upper or lower edge of the containing
-region.
-
-Then we process the right-going edges. This involves:
-
- - inserting the edges in the edge dictionary;
- - computing the winding number of any newly created active regions.
- We can compute this incrementally using the winding of each edge
- that we cross as we walk through the dictionary.
- - relinking the mesh if necessary, so that the order of these edges around
- the event vertex matches the order in the dictionary;
- - checking any newly adjacent edges for intersection and/or merging.
-
-If there are no right-going edges, again we need to add one to split
-the containing region into monotone pieces. In our case it is most
-convenient to add an edge to the leftmost right endpoint of either
-containing edge; however we may need to change this later (see the
-code for details).
-
-
-Invariants
-----------
-
-These are the most important invariants maintained during the sweep.
-We define a function VertLeq(v1,v2) which defines the order in which
-vertices cross the sweep line, and a function EdgeLeq(e1,e2; loc)
-which says whether e1 is below e2 at the sweep event location "loc".
-This function is defined only at sweep event locations which lie
-between the rightmost left endpoint of {e1,e2}, and the leftmost right
-endpoint of {e1,e2}.
-
-Invariants for the Edge Dictionary.
-
- - Each pair of adjacent edges e2=Succ(e1) satisfies EdgeLeq(e1,e2)
- at any valid location of the sweep event.
- - If EdgeLeq(e2,e1) as well (at any valid sweep event), then e1 and e2
- share a common endpoint.
- - For each e in the dictionary, e->Dst has been processed but not e->Org.
- - Each edge e satisfies VertLeq(e->Dst,event) && VertLeq(event,e->Org)
- where "event" is the current sweep line event.
- - No edge e has zero length.
- - No two edges have identical left and right endpoints.
-
-Invariants for the Mesh (the processed portion).
-
- - The portion of the mesh left of the sweep line is a planar graph,
- ie. there is *some* way to embed it in the plane.
- - No processed edge has zero length.
- - No two processed vertices have identical coordinates.
- - Each "inside" region is monotone, ie. can be broken into two chains
- of monotonically increasing vertices according to VertLeq(v1,v2)
- - a non-invariant: these chains may intersect (slightly) due to
- numerical errors, but this does not affect the algorithm's operation.
-
-Invariants for the Sweep.
-
- - If a vertex has any left-going edges, then these must be in the edge
- dictionary at the time the vertex is processed.
- - If an edge is marked "fixUpperEdge" (it is a temporary edge introduced
- by ConnectRightVertex), then it is the only right-going edge from
- its associated vertex. (This says that these edges exist only
- when it is necessary.)
-
-
-Robustness
-----------
-
-The key to the robustness of the algorithm is maintaining the
-invariants above, especially the correct ordering of the edge
-dictionary. We achieve this by:
-
- 1. Writing the numerical computations for maximum precision rather
- than maximum speed.
-
- 2. Making no assumptions at all about the results of the edge
- intersection calculations -- for sufficiently degenerate inputs,
- the computed location is not much better than a random number.
-
- 3. When numerical errors violate the invariants, restore them
- by making *topological* changes when necessary (ie. relinking
- the mesh structure).
-
-
-Triangulation and Grouping
---------------------------
-
-We finish the line sweep before doing any triangulation. This is
-because even after a monotone region is complete, there can be further
-changes to its vertex data because of further vertex merging.
-
-After triangulating all monotone regions, we want to group the
-triangles into fans and strips. We do this using a greedy approach.
-The triangulation itself is not optimized to reduce the number of
-primitives; we just try to get a reasonable decomposition of the
-computed triangulation.
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#ifndef __dict_list_h_
-#define __dict_list_h_
-
-/* Use #define's so that another heap implementation can use this one */
-
-#define DictKey DictListKey
-#define Dict DictList
-#define DictNode DictListNode
-
-#define dictNewDict(frame,leq) __gl_dictListNewDict(frame,leq)
-#define dictDeleteDict(dict) __gl_dictListDeleteDict(dict)
-
-#define dictSearch(dict,key) __gl_dictListSearch(dict,key)
-#define dictInsert(dict,key) __gl_dictListInsert(dict,key)
-#define dictInsertBefore(dict,node,key) __gl_dictListInsertBefore(dict,node,key)
-#define dictDelete(dict,node) __gl_dictListDelete(dict,node)
-
-#define dictKey(n) __gl_dictListKey(n)
-#define dictSucc(n) __gl_dictListSucc(n)
-#define dictPred(n) __gl_dictListPred(n)
-#define dictMin(d) __gl_dictListMin(d)
-#define dictMax(d) __gl_dictListMax(d)
-
-
-
-typedef void *DictKey;
-typedef struct Dict Dict;
-typedef struct DictNode DictNode;
-
-Dict *dictNewDict(
- void *frame,
- int (*leq)(void *frame, DictKey key1, DictKey key2) );
-
-void dictDeleteDict( Dict *dict );
-
-/* Search returns the node with the smallest key greater than or equal
- * to the given key. If there is no such key, returns a node whose
- * key is NULL. Similarly, Succ(Max(d)) has a NULL key, etc.
- */
-DictNode *dictSearch( Dict *dict, DictKey key );
-DictNode *dictInsertBefore( Dict *dict, DictNode *node, DictKey key );
-void dictDelete( Dict *dict, DictNode *node );
-
-#define __gl_dictListKey(n) ((n)->key)
-#define __gl_dictListSucc(n) ((n)->next)
-#define __gl_dictListPred(n) ((n)->prev)
-#define __gl_dictListMin(d) ((d)->head.next)
-#define __gl_dictListMax(d) ((d)->head.prev)
-#define __gl_dictListInsert(d,k) (dictInsertBefore((d),&(d)->head,(k)))
-
-
-/*** Private data structures ***/
-
-struct DictNode {
- DictKey key;
- DictNode *next;
- DictNode *prev;
-};
-
-struct Dict {
- DictNode head;
- void *frame;
- int (*leq)(void *frame, DictKey key1, DictKey key2);
-};
-
-#endif
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#include <stddef.h>
-#include "dict-list.h"
-#include "memalloc.h"
-
-/* really __gl_dictListNewDict */
-Dict *dictNewDict( void *frame,
- int (*leq)(void *frame, DictKey key1, DictKey key2) )
-{
- Dict *dict = (Dict *) memAlloc( sizeof( Dict ));
- DictNode *head;
-
- if (dict == NULL) return NULL;
-
- head = &dict->head;
-
- head->key = NULL;
- head->next = head;
- head->prev = head;
-
- dict->frame = frame;
- dict->leq = leq;
-
- return dict;
-}
-
-/* really __gl_dictListDeleteDict */
-void dictDeleteDict( Dict *dict )
-{
- DictNode *node, *next;
-
- for( node = dict->head.next; node != &dict->head; node = next ) {
- next = node->next;
- memFree( node );
- }
- memFree( dict );
-}
-
-/* really __gl_dictListInsertBefore */
-DictNode *dictInsertBefore( Dict *dict, DictNode *node, DictKey key )
-{
- DictNode *newNode;
-
- do {
- node = node->prev;
- } while( node->key != NULL && ! (*dict->leq)(dict->frame, node->key, key));
-
- newNode = (DictNode *) memAlloc( sizeof( DictNode ));
- if (newNode == NULL) return NULL;
-
- newNode->key = key;
- newNode->next = node->next;
- node->next->prev = newNode;
- newNode->prev = node;
- node->next = newNode;
-
- return newNode;
-}
-
-/* really __gl_dictListDelete */
-void dictDelete( Dict *dict, DictNode *node ) /*ARGSUSED*/
-{
- node->next->prev = node->prev;
- node->prev->next = node->next;
- memFree( node );
-}
-
-/* really __gl_dictListSearch */
-DictNode *dictSearch( Dict *dict, DictKey key )
-{
- DictNode *node = &dict->head;
-
- do {
- node = node->next;
- } while( node->key != NULL && ! (*dict->leq)(dict->frame, key, node->key));
-
- return node;
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#ifndef __dict_list_h_
-#define __dict_list_h_
-
-/* Use #define's so that another heap implementation can use this one */
-
-#define DictKey DictListKey
-#define Dict DictList
-#define DictNode DictListNode
-
-#define dictNewDict(frame,leq) __gl_dictListNewDict(frame,leq)
-#define dictDeleteDict(dict) __gl_dictListDeleteDict(dict)
-
-#define dictSearch(dict,key) __gl_dictListSearch(dict,key)
-#define dictInsert(dict,key) __gl_dictListInsert(dict,key)
-#define dictInsertBefore(dict,node,key) __gl_dictListInsertBefore(dict,node,key)
-#define dictDelete(dict,node) __gl_dictListDelete(dict,node)
-
-#define dictKey(n) __gl_dictListKey(n)
-#define dictSucc(n) __gl_dictListSucc(n)
-#define dictPred(n) __gl_dictListPred(n)
-#define dictMin(d) __gl_dictListMin(d)
-#define dictMax(d) __gl_dictListMax(d)
-
-
-
-typedef void *DictKey;
-typedef struct Dict Dict;
-typedef struct DictNode DictNode;
-
-Dict *dictNewDict(
- void *frame,
- int (*leq)(void *frame, DictKey key1, DictKey key2) );
-
-void dictDeleteDict( Dict *dict );
-
-/* Search returns the node with the smallest key greater than or equal
- * to the given key. If there is no such key, returns a node whose
- * key is NULL. Similarly, Succ(Max(d)) has a NULL key, etc.
- */
-DictNode *dictSearch( Dict *dict, DictKey key );
-DictNode *dictInsertBefore( Dict *dict, DictNode *node, DictKey key );
-void dictDelete( Dict *dict, DictNode *node );
-
-#define __gl_dictListKey(n) ((n)->key)
-#define __gl_dictListSucc(n) ((n)->next)
-#define __gl_dictListPred(n) ((n)->prev)
-#define __gl_dictListMin(d) ((d)->head.next)
-#define __gl_dictListMax(d) ((d)->head.prev)
-#define __gl_dictListInsert(d,k) (dictInsertBefore((d),&(d)->head,(k)))
-
-
-/*** Private data structures ***/
-
-struct DictNode {
- DictKey key;
- DictNode *next;
- DictNode *prev;
-};
-
-struct Dict {
- DictNode head;
- void *frame;
- int (*leq)(void *frame, DictKey key1, DictKey key2);
-};
-
-#endif
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#include "gluos.h"
-#include <assert.h>
-#include "mesh.h"
-#include "geom.h"
-
-int __gl_vertLeq( GLUvertex *u, GLUvertex *v )
-{
- /* Returns TRUE if u is lexicographically <= v. */
-
- return VertLeq( u, v );
-}
-
-GLdouble __gl_edgeEval( GLUvertex *u, GLUvertex *v, GLUvertex *w )
-{
- /* Given three vertices u,v,w such that VertLeq(u,v) && VertLeq(v,w),
- * evaluates the t-coord of the edge uw at the s-coord of the vertex v.
- * Returns v->t - (uw)(v->s), ie. the signed distance from uw to v.
- * If uw is vertical (and thus passes thru v), the result is zero.
- *
- * The calculation is extremely accurate and stable, even when v
- * is very close to u or w. In particular if we set v->t = 0 and
- * let r be the negated result (this evaluates (uw)(v->s)), then
- * r is guaranteed to satisfy MIN(u->t,w->t) <= r <= MAX(u->t,w->t).
- */
- GLdouble gapL, gapR;
-
- assert( VertLeq( u, v ) && VertLeq( v, w ));
-
- gapL = v->s - u->s;
- gapR = w->s - v->s;
-
- if( gapL + gapR > 0 ) {
- if( gapL < gapR ) {
- return (v->t - u->t) + (u->t - w->t) * (gapL / (gapL + gapR));
- } else {
- return (v->t - w->t) + (w->t - u->t) * (gapR / (gapL + gapR));
- }
- }
- /* vertical line */
- return 0;
-}
-
-GLdouble __gl_edgeSign( GLUvertex *u, GLUvertex *v, GLUvertex *w )
-{
- /* Returns a number whose sign matches EdgeEval(u,v,w) but which
- * is cheaper to evaluate. Returns > 0, == 0 , or < 0
- * as v is above, on, or below the edge uw.
- */
- GLdouble gapL, gapR;
-
- assert( VertLeq( u, v ) && VertLeq( v, w ));
-
- gapL = v->s - u->s;
- gapR = w->s - v->s;
-
- if( gapL + gapR > 0 ) {
- return (v->t - w->t) * gapL + (v->t - u->t) * gapR;
- }
- /* vertical line */
- return 0;
-}
-
-
-/***********************************************************************
- * Define versions of EdgeSign, EdgeEval with s and t transposed.
- */
-
-GLdouble __gl_transEval( GLUvertex *u, GLUvertex *v, GLUvertex *w )
-{
- /* Given three vertices u,v,w such that TransLeq(u,v) && TransLeq(v,w),
- * evaluates the t-coord of the edge uw at the s-coord of the vertex v.
- * Returns v->s - (uw)(v->t), ie. the signed distance from uw to v.
- * If uw is vertical (and thus passes thru v), the result is zero.
- *
- * The calculation is extremely accurate and stable, even when v
- * is very close to u or w. In particular if we set v->s = 0 and
- * let r be the negated result (this evaluates (uw)(v->t)), then
- * r is guaranteed to satisfy MIN(u->s,w->s) <= r <= MAX(u->s,w->s).
- */
- GLdouble gapL, gapR;
-
- assert( TransLeq( u, v ) && TransLeq( v, w ));
-
- gapL = v->t - u->t;
- gapR = w->t - v->t;
-
- if( gapL + gapR > 0 ) {
- if( gapL < gapR ) {
- return (v->s - u->s) + (u->s - w->s) * (gapL / (gapL + gapR));
- } else {
- return (v->s - w->s) + (w->s - u->s) * (gapR / (gapL + gapR));
- }
- }
- /* vertical line */
- return 0;
-}
-
-GLdouble __gl_transSign( GLUvertex *u, GLUvertex *v, GLUvertex *w )
-{
- /* Returns a number whose sign matches TransEval(u,v,w) but which
- * is cheaper to evaluate. Returns > 0, == 0 , or < 0
- * as v is above, on, or below the edge uw.
- */
- GLdouble gapL, gapR;
-
- assert( TransLeq( u, v ) && TransLeq( v, w ));
-
- gapL = v->t - u->t;
- gapR = w->t - v->t;
-
- if( gapL + gapR > 0 ) {
- return (v->s - w->s) * gapL + (v->s - u->s) * gapR;
- }
- /* vertical line */
- return 0;
-}
-
-
-int __gl_vertCCW( GLUvertex *u, GLUvertex *v, GLUvertex *w )
-{
- /* For almost-degenerate situations, the results are not reliable.
- * Unless the floating-point arithmetic can be performed without
- * rounding errors, *any* implementation will give incorrect results
- * on some degenerate inputs, so the client must have some way to
- * handle this situation.
- */
- return (u->s*(v->t - w->t) + v->s*(w->t - u->t) + w->s*(u->t - v->t)) >= 0;
-}
-
-/* Given parameters a,x,b,y returns the value (b*x+a*y)/(a+b),
- * or (x+y)/2 if a==b==0. It requires that a,b >= 0, and enforces
- * this in the rare case that one argument is slightly negative.
- * The implementation is extremely stable numerically.
- * In particular it guarantees that the result r satisfies
- * MIN(x,y) <= r <= MAX(x,y), and the results are very accurate
- * even when a and b differ greatly in magnitude.
- */
-#define RealInterpolate(a,x,b,y) \
- (a = (a < 0) ? 0 : a, b = (b < 0) ? 0 : b, \
- ((a <= b) ? ((b == 0) ? ((x+y) / 2) \
- : (x + (y-x) * (a/(a+b)))) \
- : (y + (x-y) * (b/(a+b)))))
-
-#ifndef FOR_TRITE_TEST_PROGRAM
-#define Interpolate(a,x,b,y) RealInterpolate(a,x,b,y)
-#else
-
-/* Claim: the ONLY property the sweep algorithm relies on is that
- * MIN(x,y) <= r <= MAX(x,y). This is a nasty way to test that.
- */
-#include <stdlib.h>
-extern int RandomInterpolate;
-
-GLdouble Interpolate( GLdouble a, GLdouble x, GLdouble b, GLdouble y)
-{
-printf("*********************%d\n",RandomInterpolate);
- if( RandomInterpolate ) {
- a = 1.2 * drand48() - 0.1;
- a = (a < 0) ? 0 : ((a > 1) ? 1 : a);
- b = 1.0 - a;
- }
- return RealInterpolate(a,x,b,y);
-}
-
-#endif
-
-#define Swap(a,b) do { GLUvertex *t = a; a = b; b = t; } while (0)
-
-void __gl_edgeIntersect( GLUvertex *o1, GLUvertex *d1,
- GLUvertex *o2, GLUvertex *d2,
- GLUvertex *v )
-/* Given edges (o1,d1) and (o2,d2), compute their point of intersection.
- * The computed point is guaranteed to lie in the intersection of the
- * bounding rectangles defined by each edge.
- */
-{
- GLdouble z1, z2;
-
- /* This is certainly not the most efficient way to find the intersection
- * of two line segments, but it is very numerically stable.
- *
- * Strategy: find the two middle vertices in the VertLeq ordering,
- * and interpolate the intersection s-value from these. Then repeat
- * using the TransLeq ordering to find the intersection t-value.
- */
-
- if( ! VertLeq( o1, d1 )) { Swap( o1, d1 ); }
- if( ! VertLeq( o2, d2 )) { Swap( o2, d2 ); }
- if( ! VertLeq( o1, o2 )) { Swap( o1, o2 ); Swap( d1, d2 ); }
-
- if( ! VertLeq( o2, d1 )) {
- /* Technically, no intersection -- do our best */
- v->s = (o2->s + d1->s) / 2;
- } else if( VertLeq( d1, d2 )) {
- /* Interpolate between o2 and d1 */
- z1 = EdgeEval( o1, o2, d1 );
- z2 = EdgeEval( o2, d1, d2 );
- if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; }
- v->s = Interpolate( z1, o2->s, z2, d1->s );
- } else {
- /* Interpolate between o2 and d2 */
- z1 = EdgeSign( o1, o2, d1 );
- z2 = -EdgeSign( o1, d2, d1 );
- if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; }
- v->s = Interpolate( z1, o2->s, z2, d2->s );
- }
-
- /* Now repeat the process for t */
-
- if( ! TransLeq( o1, d1 )) { Swap( o1, d1 ); }
- if( ! TransLeq( o2, d2 )) { Swap( o2, d2 ); }
- if( ! TransLeq( o1, o2 )) { Swap( o1, o2 ); Swap( d1, d2 ); }
-
- if( ! TransLeq( o2, d1 )) {
- /* Technically, no intersection -- do our best */
- v->t = (o2->t + d1->t) / 2;
- } else if( TransLeq( d1, d2 )) {
- /* Interpolate between o2 and d1 */
- z1 = TransEval( o1, o2, d1 );
- z2 = TransEval( o2, d1, d2 );
- if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; }
- v->t = Interpolate( z1, o2->t, z2, d1->t );
- } else {
- /* Interpolate between o2 and d2 */
- z1 = TransSign( o1, o2, d1 );
- z2 = -TransSign( o1, d2, d1 );
- if( z1+z2 < 0 ) { z1 = -z1; z2 = -z2; }
- v->t = Interpolate( z1, o2->t, z2, d2->t );
- }
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#ifndef __geom_h_
-#define __geom_h_
-
-#include "mesh.h"
-
-#ifdef NO_BRANCH_CONDITIONS
-/* MIPS architecture has special instructions to evaluate boolean
- * conditions -- more efficient than branching, IF you can get the
- * compiler to generate the right instructions (SGI compiler doesn't)
- */
-#define VertEq(u,v) (((u)->s == (v)->s) & ((u)->t == (v)->t))
-#define VertLeq(u,v) (((u)->s < (v)->s) | \
- ((u)->s == (v)->s & (u)->t <= (v)->t))
-#else
-#define VertEq(u,v) ((u)->s == (v)->s && (u)->t == (v)->t)
-#define VertLeq(u,v) (((u)->s < (v)->s) || \
- ((u)->s == (v)->s && (u)->t <= (v)->t))
-#endif
-
-#define EdgeEval(u,v,w) __gl_edgeEval(u,v,w)
-#define EdgeSign(u,v,w) __gl_edgeSign(u,v,w)
-
-/* Versions of VertLeq, EdgeSign, EdgeEval with s and t transposed. */
-
-#define TransLeq(u,v) (((u)->t < (v)->t) || \
- ((u)->t == (v)->t && (u)->s <= (v)->s))
-#define TransEval(u,v,w) __gl_transEval(u,v,w)
-#define TransSign(u,v,w) __gl_transSign(u,v,w)
-
-
-#define EdgeGoesLeft(e) VertLeq( (e)->Dst, (e)->Org )
-#define EdgeGoesRight(e) VertLeq( (e)->Org, (e)->Dst )
-
-#undef ABS
-#define ABS(x) ((x) < 0 ? -(x) : (x))
-#define VertL1dist(u,v) (ABS(u->s - v->s) + ABS(u->t - v->t))
-
-#define VertCCW(u,v,w) __gl_vertCCW(u,v,w)
-
-int __gl_vertLeq( GLUvertex *u, GLUvertex *v );
-GLdouble __gl_edgeEval( GLUvertex *u, GLUvertex *v, GLUvertex *w );
-GLdouble __gl_edgeSign( GLUvertex *u, GLUvertex *v, GLUvertex *w );
-GLdouble __gl_transEval( GLUvertex *u, GLUvertex *v, GLUvertex *w );
-GLdouble __gl_transSign( GLUvertex *u, GLUvertex *v, GLUvertex *w );
-int __gl_vertCCW( GLUvertex *u, GLUvertex *v, GLUvertex *w );
-void __gl_edgeIntersect( GLUvertex *o1, GLUvertex *d1,
- GLUvertex *o2, GLUvertex *d2,
- GLUvertex *v );
-
-#endif
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#include "memalloc.h"
-#include "string.h"
-
-int __gl_memInit( size_t maxFast )
-{
-#ifndef NO_MALLOPT
-/* mallopt( M_MXFAST, maxFast );*/
-#ifdef MEMORY_DEBUG
- mallopt( M_DEBUG, 1 );
-#endif
-#endif
- return 1;
-}
-
-#ifdef MEMORY_DEBUG
-void *__gl_memAlloc( size_t n )
-{
- return memset( malloc( n ), 0xa5, n );
-}
-#endif
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#ifndef __memalloc_simple_h_
-#define __memalloc_simple_h_
-
-#include <stdlib.h>
-
-#define memRealloc realloc
-#define memFree free
-
-#define memInit __gl_memInit
-/*extern void __gl_memInit( size_t );*/
-extern int __gl_memInit( size_t );
-
-#ifndef MEMORY_DEBUG
-#define memAlloc malloc
-#else
-#define memAlloc __gl_memAlloc
-extern void * __gl_memAlloc( size_t );
-#endif
-
-#endif
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#include "gluos.h"
-#include <stddef.h>
-#include <assert.h>
-#include "mesh.h"
-#include "memalloc.h"
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-static GLUvertex *allocVertex()
-{
- return (GLUvertex *)memAlloc( sizeof( GLUvertex ));
-}
-
-static GLUface *allocFace()
-{
- return (GLUface *)memAlloc( sizeof( GLUface ));
-}
-
-/************************ Utility Routines ************************/
-
-/* Allocate and free half-edges in pairs for efficiency.
- * The *only* place that should use this fact is allocation/free.
- */
-typedef struct { GLUhalfEdge e, eSym; } EdgePair;
-
-/* MakeEdge creates a new pair of half-edges which form their own loop.
- * No vertex or face structures are allocated, but these must be assigned
- * before the current edge operation is completed.
- */
-static GLUhalfEdge *MakeEdge( GLUhalfEdge *eNext )
-{
- GLUhalfEdge *e;
- GLUhalfEdge *eSym;
- GLUhalfEdge *ePrev;
- EdgePair *pair = (EdgePair *)memAlloc( sizeof( EdgePair ));
- if (pair == NULL) return NULL;
-
- e = &pair->e;
- eSym = &pair->eSym;
-
- /* Make sure eNext points to the first edge of the edge pair */
- if( eNext->Sym < eNext ) { eNext = eNext->Sym; }
-
- /* Insert in circular doubly-linked list before eNext.
- * Note that the prev pointer is stored in Sym->next.
- */
- ePrev = eNext->Sym->next;
- eSym->next = ePrev;
- ePrev->Sym->next = e;
- e->next = eNext;
- eNext->Sym->next = eSym;
-
- e->Sym = eSym;
- e->Onext = e;
- e->Lnext = eSym;
- e->Org = NULL;
- e->Lface = NULL;
- e->winding = 0;
- e->activeRegion = NULL;
-
- eSym->Sym = e;
- eSym->Onext = eSym;
- eSym->Lnext = e;
- eSym->Org = NULL;
- eSym->Lface = NULL;
- eSym->winding = 0;
- eSym->activeRegion = NULL;
-
- return e;
-}
-
-/* Splice( a, b ) is best described by the Guibas/Stolfi paper or the
- * CS348a notes (see mesh.h). Basically it modifies the mesh so that
- * a->Onext and b->Onext are exchanged. This can have various effects
- * depending on whether a and b belong to different face or vertex rings.
- * For more explanation see __gl_meshSplice() below.
- */
-static void Splice( GLUhalfEdge *a, GLUhalfEdge *b )
-{
- GLUhalfEdge *aOnext = a->Onext;
- GLUhalfEdge *bOnext = b->Onext;
-
- aOnext->Sym->Lnext = b;
- bOnext->Sym->Lnext = a;
- a->Onext = bOnext;
- b->Onext = aOnext;
-}
-
-/* MakeVertex( newVertex, eOrig, vNext ) attaches a new vertex and makes it the
- * origin of all edges in the vertex loop to which eOrig belongs. "vNext" gives
- * a place to insert the new vertex in the global vertex list. We insert
- * the new vertex *before* vNext so that algorithms which walk the vertex
- * list will not see the newly created vertices.
- */
-static void MakeVertex( GLUvertex *newVertex,
- GLUhalfEdge *eOrig, GLUvertex *vNext )
-{
- GLUhalfEdge *e;
- GLUvertex *vPrev;
- GLUvertex *vNew = newVertex;
-
- assert(vNew != NULL);
-
- /* insert in circular doubly-linked list before vNext */
- vPrev = vNext->prev;
- vNew->prev = vPrev;
- vPrev->next = vNew;
- vNew->next = vNext;
- vNext->prev = vNew;
-
- vNew->anEdge = eOrig;
- vNew->data = NULL;
- /* leave coords, s, t undefined */
-
- /* fix other edges on this vertex loop */
- e = eOrig;
- do {
- e->Org = vNew;
- e = e->Onext;
- } while( e != eOrig );
-}
-
-/* MakeFace( newFace, eOrig, fNext ) attaches a new face and makes it the left
- * face of all edges in the face loop to which eOrig belongs. "fNext" gives
- * a place to insert the new face in the global face list. We insert
- * the new face *before* fNext so that algorithms which walk the face
- * list will not see the newly created faces.
- */
-static void MakeFace( GLUface *newFace, GLUhalfEdge *eOrig, GLUface *fNext )
-{
- GLUhalfEdge *e;
- GLUface *fPrev;
- GLUface *fNew = newFace;
-
- assert(fNew != NULL);
-
- /* insert in circular doubly-linked list before fNext */
- fPrev = fNext->prev;
- fNew->prev = fPrev;
- fPrev->next = fNew;
- fNew->next = fNext;
- fNext->prev = fNew;
-
- fNew->anEdge = eOrig;
- fNew->data = NULL;
- fNew->trail = NULL;
- fNew->marked = FALSE;
-
- /* The new face is marked "inside" if the old one was. This is a
- * convenience for the common case where a face has been split in two.
- */
- fNew->inside = fNext->inside;
-
- /* fix other edges on this face loop */
- e = eOrig;
- do {
- e->Lface = fNew;
- e = e->Lnext;
- } while( e != eOrig );
-}
-
-/* KillEdge( eDel ) destroys an edge (the half-edges eDel and eDel->Sym),
- * and removes from the global edge list.
- */
-static void KillEdge( GLUhalfEdge *eDel )
-{
- GLUhalfEdge *ePrev, *eNext;
-
- /* Half-edges are allocated in pairs, see EdgePair above */
- if( eDel->Sym < eDel ) { eDel = eDel->Sym; }
-
- /* delete from circular doubly-linked list */
- eNext = eDel->next;
- ePrev = eDel->Sym->next;
- eNext->Sym->next = ePrev;
- ePrev->Sym->next = eNext;
-
- memFree( eDel );
-}
-
-
-/* KillVertex( vDel ) destroys a vertex and removes it from the global
- * vertex list. It updates the vertex loop to point to a given new vertex.
- */
-static void KillVertex( GLUvertex *vDel, GLUvertex *newOrg )
-{
- GLUhalfEdge *e, *eStart = vDel->anEdge;
- GLUvertex *vPrev, *vNext;
-
- /* change the origin of all affected edges */
- e = eStart;
- do {
- e->Org = newOrg;
- e = e->Onext;
- } while( e != eStart );
-
- /* delete from circular doubly-linked list */
- vPrev = vDel->prev;
- vNext = vDel->next;
- vNext->prev = vPrev;
- vPrev->next = vNext;
-
- memFree( vDel );
-}
-
-/* KillFace( fDel ) destroys a face and removes it from the global face
- * list. It updates the face loop to point to a given new face.
- */
-static void KillFace( GLUface *fDel, GLUface *newLface )
-{
- GLUhalfEdge *e, *eStart = fDel->anEdge;
- GLUface *fPrev, *fNext;
-
- /* change the left face of all affected edges */
- e = eStart;
- do {
- e->Lface = newLface;
- e = e->Lnext;
- } while( e != eStart );
-
- /* delete from circular doubly-linked list */
- fPrev = fDel->prev;
- fNext = fDel->next;
- fNext->prev = fPrev;
- fPrev->next = fNext;
-
- memFree( fDel );
-}
-
-
-/****************** Basic Edge Operations **********************/
-
-/* __gl_meshMakeEdge creates one edge, two vertices, and a loop (face).
- * The loop consists of the two new half-edges.
- */
-GLUhalfEdge *__gl_meshMakeEdge( GLUmesh *mesh )
-{
- GLUvertex *newVertex1= allocVertex();
- GLUvertex *newVertex2= allocVertex();
- GLUface *newFace= allocFace();
- GLUhalfEdge *e;
-
- /* if any one is null then all get freed */
- if (newVertex1 == NULL || newVertex2 == NULL || newFace == NULL) {
- if (newVertex1 != NULL) memFree(newVertex1);
- if (newVertex2 != NULL) memFree(newVertex2);
- if (newFace != NULL) memFree(newFace);
- return NULL;
- }
-
- e = MakeEdge( &mesh->eHead );
- if (e == NULL) {
- memFree(newVertex1);
- memFree(newVertex2);
- memFree(newFace);
- return NULL;
- }
-
- MakeVertex( newVertex1, e, &mesh->vHead );
- MakeVertex( newVertex2, e->Sym, &mesh->vHead );
- MakeFace( newFace, e, &mesh->fHead );
- return e;
-}
-
-
-/* __gl_meshSplice( eOrg, eDst ) is the basic operation for changing the
- * mesh connectivity and topology. It changes the mesh so that
- * eOrg->Onext <- OLD( eDst->Onext )
- * eDst->Onext <- OLD( eOrg->Onext )
- * where OLD(...) means the value before the meshSplice operation.
- *
- * This can have two effects on the vertex structure:
- * - if eOrg->Org != eDst->Org, the two vertices are merged together
- * - if eOrg->Org == eDst->Org, the origin is split into two vertices
- * In both cases, eDst->Org is changed and eOrg->Org is untouched.
- *
- * Similarly (and independently) for the face structure,
- * - if eOrg->Lface == eDst->Lface, one loop is split into two
- * - if eOrg->Lface != eDst->Lface, two distinct loops are joined into one
- * In both cases, eDst->Lface is changed and eOrg->Lface is unaffected.
- *
- * Some special cases:
- * If eDst == eOrg, the operation has no effect.
- * If eDst == eOrg->Lnext, the new face will have a single edge.
- * If eDst == eOrg->Lprev, the old face will have a single edge.
- * If eDst == eOrg->Onext, the new vertex will have a single edge.
- * If eDst == eOrg->Oprev, the old vertex will have a single edge.
- */
-int __gl_meshSplice( GLUhalfEdge *eOrg, GLUhalfEdge *eDst )
-{
- int joiningLoops = FALSE;
- int joiningVertices = FALSE;
-
- if( eOrg == eDst ) return 1;
-
- if( eDst->Org != eOrg->Org ) {
- /* We are merging two disjoint vertices -- destroy eDst->Org */
- joiningVertices = TRUE;
- KillVertex( eDst->Org, eOrg->Org );
- }
- if( eDst->Lface != eOrg->Lface ) {
- /* We are connecting two disjoint loops -- destroy eDst->Lface */
- joiningLoops = TRUE;
- KillFace( eDst->Lface, eOrg->Lface );
- }
-
- /* Change the edge structure */
- Splice( eDst, eOrg );
-
- if( ! joiningVertices ) {
- GLUvertex *newVertex= allocVertex();
- if (newVertex == NULL) return 0;
-
- /* We split one vertex into two -- the new vertex is eDst->Org.
- * Make sure the old vertex points to a valid half-edge.
- */
- MakeVertex( newVertex, eDst, eOrg->Org );
- eOrg->Org->anEdge = eOrg;
- }
- if( ! joiningLoops ) {
- GLUface *newFace= allocFace();
- if (newFace == NULL) return 0;
-
- /* We split one loop into two -- the new loop is eDst->Lface.
- * Make sure the old face points to a valid half-edge.
- */
- MakeFace( newFace, eDst, eOrg->Lface );
- eOrg->Lface->anEdge = eOrg;
- }
-
- return 1;
-}
-
-
-/* __gl_meshDelete( eDel ) removes the edge eDel. There are several cases:
- * if (eDel->Lface != eDel->Rface), we join two loops into one; the loop
- * eDel->Lface is deleted. Otherwise, we are splitting one loop into two;
- * the newly created loop will contain eDel->Dst. If the deletion of eDel
- * would create isolated vertices, those are deleted as well.
- *
- * This function could be implemented as two calls to __gl_meshSplice
- * plus a few calls to memFree, but this would allocate and delete
- * unnecessary vertices and faces.
- */
-int __gl_meshDelete( GLUhalfEdge *eDel )
-{
- GLUhalfEdge *eDelSym = eDel->Sym;
- int joiningLoops = FALSE;
-
- /* First step: disconnect the origin vertex eDel->Org. We make all
- * changes to get a consistent mesh in this "intermediate" state.
- */
- if( eDel->Lface != eDel->Rface ) {
- /* We are joining two loops into one -- remove the left face */
- joiningLoops = TRUE;
- KillFace( eDel->Lface, eDel->Rface );
- }
-
- if( eDel->Onext == eDel ) {
- KillVertex( eDel->Org, NULL );
- } else {
- /* Make sure that eDel->Org and eDel->Rface point to valid half-edges */
- eDel->Rface->anEdge = eDel->Oprev;
- eDel->Org->anEdge = eDel->Onext;
-
- Splice( eDel, eDel->Oprev );
- if( ! joiningLoops ) {
- GLUface *newFace= allocFace();
- if (newFace == NULL) return 0;
-
- /* We are splitting one loop into two -- create a new loop for eDel. */
- MakeFace( newFace, eDel, eDel->Lface );
- }
- }
-
- /* Claim: the mesh is now in a consistent state, except that eDel->Org
- * may have been deleted. Now we disconnect eDel->Dst.
- */
- if( eDelSym->Onext == eDelSym ) {
- KillVertex( eDelSym->Org, NULL );
- KillFace( eDelSym->Lface, NULL );
- } else {
- /* Make sure that eDel->Dst and eDel->Lface point to valid half-edges */
- eDel->Lface->anEdge = eDelSym->Oprev;
- eDelSym->Org->anEdge = eDelSym->Onext;
- Splice( eDelSym, eDelSym->Oprev );
- }
-
- /* Any isolated vertices or faces have already been freed. */
- KillEdge( eDel );
-
- return 1;
-}
-
-
-/******************** Other Edge Operations **********************/
-
-/* All these routines can be implemented with the basic edge
- * operations above. They are provided for convenience and efficiency.
- */
-
-
-/* __gl_meshAddEdgeVertex( eOrg ) creates a new edge eNew such that
- * eNew == eOrg->Lnext, and eNew->Dst is a newly created vertex.
- * eOrg and eNew will have the same left face.
- */
-GLUhalfEdge *__gl_meshAddEdgeVertex( GLUhalfEdge *eOrg )
-{
- GLUhalfEdge *eNewSym;
- GLUhalfEdge *eNew = MakeEdge( eOrg );
- if (eNew == NULL) return NULL;
-
- eNewSym = eNew->Sym;
-
- /* Connect the new edge appropriately */
- Splice( eNew, eOrg->Lnext );
-
- /* Set the vertex and face information */
- eNew->Org = eOrg->Dst;
- {
- GLUvertex *newVertex= allocVertex();
- if (newVertex == NULL) return NULL;
-
- MakeVertex( newVertex, eNewSym, eNew->Org );
- }
- eNew->Lface = eNewSym->Lface = eOrg->Lface;
-
- return eNew;
-}
-
-
-/* __gl_meshSplitEdge( eOrg ) splits eOrg into two edges eOrg and eNew,
- * such that eNew == eOrg->Lnext. The new vertex is eOrg->Dst == eNew->Org.
- * eOrg and eNew will have the same left face.
- */
-GLUhalfEdge *__gl_meshSplitEdge( GLUhalfEdge *eOrg )
-{
- GLUhalfEdge *eNew;
- GLUhalfEdge *tempHalfEdge= __gl_meshAddEdgeVertex( eOrg );
- if (tempHalfEdge == NULL) return NULL;
-
- eNew = tempHalfEdge->Sym;
-
- /* Disconnect eOrg from eOrg->Dst and connect it to eNew->Org */
- Splice( eOrg->Sym, eOrg->Sym->Oprev );
- Splice( eOrg->Sym, eNew );
-
- /* Set the vertex and face information */
- eOrg->Dst = eNew->Org;
- eNew->Dst->anEdge = eNew->Sym; /* may have pointed to eOrg->Sym */
- eNew->Rface = eOrg->Rface;
- eNew->winding = eOrg->winding; /* copy old winding information */
- eNew->Sym->winding = eOrg->Sym->winding;
-
- return eNew;
-}
-
-
-/* __gl_meshConnect( eOrg, eDst ) creates a new edge from eOrg->Dst
- * to eDst->Org, and returns the corresponding half-edge eNew.
- * If eOrg->Lface == eDst->Lface, this splits one loop into two,
- * and the newly created loop is eNew->Lface. Otherwise, two disjoint
- * loops are merged into one, and the loop eDst->Lface is destroyed.
- *
- * If (eOrg == eDst), the new face will have only two edges.
- * If (eOrg->Lnext == eDst), the old face is reduced to a single edge.
- * If (eOrg->Lnext->Lnext == eDst), the old face is reduced to two edges.
- */
-GLUhalfEdge *__gl_meshConnect( GLUhalfEdge *eOrg, GLUhalfEdge *eDst )
-{
- GLUhalfEdge *eNewSym;
- int joiningLoops = FALSE;
- GLUhalfEdge *eNew = MakeEdge( eOrg );
- if (eNew == NULL) return NULL;
-
- eNewSym = eNew->Sym;
-
- if( eDst->Lface != eOrg->Lface ) {
- /* We are connecting two disjoint loops -- destroy eDst->Lface */
- joiningLoops = TRUE;
- KillFace( eDst->Lface, eOrg->Lface );
- }
-
- /* Connect the new edge appropriately */
- Splice( eNew, eOrg->Lnext );
- Splice( eNewSym, eDst );
-
- /* Set the vertex and face information */
- eNew->Org = eOrg->Dst;
- eNewSym->Org = eDst->Org;
- eNew->Lface = eNewSym->Lface = eOrg->Lface;
-
- /* Make sure the old face points to a valid half-edge */
- eOrg->Lface->anEdge = eNewSym;
-
- if( ! joiningLoops ) {
- GLUface *newFace= allocFace();
- if (newFace == NULL) return NULL;
-
- /* We split one loop into two -- the new loop is eNew->Lface */
- MakeFace( newFace, eNew, eOrg->Lface );
- }
- return eNew;
-}
-
-
-/******************** Other Operations **********************/
-
-/* __gl_meshZapFace( fZap ) destroys a face and removes it from the
- * global face list. All edges of fZap will have a NULL pointer as their
- * left face. Any edges which also have a NULL pointer as their right face
- * are deleted entirely (along with any isolated vertices this produces).
- * An entire mesh can be deleted by zapping its faces, one at a time,
- * in any order. Zapped faces cannot be used in further mesh operations!
- */
-void __gl_meshZapFace( GLUface *fZap )
-{
- GLUhalfEdge *eStart = fZap->anEdge;
- GLUhalfEdge *e, *eNext, *eSym;
- GLUface *fPrev, *fNext;
-
- /* walk around face, deleting edges whose right face is also NULL */
- eNext = eStart->Lnext;
- do {
- e = eNext;
- eNext = e->Lnext;
-
- e->Lface = NULL;
- if( e->Rface == NULL ) {
- /* delete the edge -- see __gl_MeshDelete above */
-
- if( e->Onext == e ) {
- KillVertex( e->Org, NULL );
- } else {
- /* Make sure that e->Org points to a valid half-edge */
- e->Org->anEdge = e->Onext;
- Splice( e, e->Oprev );
- }
- eSym = e->Sym;
- if( eSym->Onext == eSym ) {
- KillVertex( eSym->Org, NULL );
- } else {
- /* Make sure that eSym->Org points to a valid half-edge */
- eSym->Org->anEdge = eSym->Onext;
- Splice( eSym, eSym->Oprev );
- }
- KillEdge( e );
- }
- } while( e != eStart );
-
- /* delete from circular doubly-linked list */
- fPrev = fZap->prev;
- fNext = fZap->next;
- fNext->prev = fPrev;
- fPrev->next = fNext;
-
- memFree( fZap );
-}
-
-
-/* __gl_meshNewMesh() creates a new mesh with no edges, no vertices,
- * and no loops (what we usually call a "face").
- */
-GLUmesh *__gl_meshNewMesh( void )
-{
- GLUvertex *v;
- GLUface *f;
- GLUhalfEdge *e;
- GLUhalfEdge *eSym;
- GLUmesh *mesh = (GLUmesh *)memAlloc( sizeof( GLUmesh ));
- if (mesh == NULL) {
- return NULL;
- }
-
- v = &mesh->vHead;
- f = &mesh->fHead;
- e = &mesh->eHead;
- eSym = &mesh->eHeadSym;
-
- v->next = v->prev = v;
- v->anEdge = NULL;
- v->data = NULL;
-
- f->next = f->prev = f;
- f->anEdge = NULL;
- f->data = NULL;
- f->trail = NULL;
- f->marked = FALSE;
- f->inside = FALSE;
-
- e->next = e;
- e->Sym = eSym;
- e->Onext = NULL;
- e->Lnext = NULL;
- e->Org = NULL;
- e->Lface = NULL;
- e->winding = 0;
- e->activeRegion = NULL;
-
- eSym->next = eSym;
- eSym->Sym = e;
- eSym->Onext = NULL;
- eSym->Lnext = NULL;
- eSym->Org = NULL;
- eSym->Lface = NULL;
- eSym->winding = 0;
- eSym->activeRegion = NULL;
-
- return mesh;
-}
-
-
-/* __gl_meshUnion( mesh1, mesh2 ) forms the union of all structures in
- * both meshes, and returns the new mesh (the old meshes are destroyed).
- */
-GLUmesh *__gl_meshUnion( GLUmesh *mesh1, GLUmesh *mesh2 )
-{
- GLUface *f1 = &mesh1->fHead;
- GLUvertex *v1 = &mesh1->vHead;
- GLUhalfEdge *e1 = &mesh1->eHead;
- GLUface *f2 = &mesh2->fHead;
- GLUvertex *v2 = &mesh2->vHead;
- GLUhalfEdge *e2 = &mesh2->eHead;
-
- /* Add the faces, vertices, and edges of mesh2 to those of mesh1 */
- if( f2->next != f2 ) {
- f1->prev->next = f2->next;
- f2->next->prev = f1->prev;
- f2->prev->next = f1;
- f1->prev = f2->prev;
- }
-
- if( v2->next != v2 ) {
- v1->prev->next = v2->next;
- v2->next->prev = v1->prev;
- v2->prev->next = v1;
- v1->prev = v2->prev;
- }
-
- if( e2->next != e2 ) {
- e1->Sym->next->Sym->next = e2->next;
- e2->next->Sym->next = e1->Sym->next;
- e2->Sym->next->Sym->next = e1;
- e1->Sym->next = e2->Sym->next;
- }
-
- memFree( mesh2 );
- return mesh1;
-}
-
-
-#ifdef DELETE_BY_ZAPPING
-
-/* __gl_meshDeleteMesh( mesh ) will free all storage for any valid mesh.
- */
-void __gl_meshDeleteMesh( GLUmesh *mesh )
-{
- GLUface *fHead = &mesh->fHead;
-
- while( fHead->next != fHead ) {
- __gl_meshZapFace( fHead->next );
- }
- assert( mesh->vHead.next == &mesh->vHead );
-
- memFree( mesh );
-}
-
-#else
-
-/* __gl_meshDeleteMesh( mesh ) will free all storage for any valid mesh.
- */
-void __gl_meshDeleteMesh( GLUmesh *mesh )
-{
- GLUface *f, *fNext;
- GLUvertex *v, *vNext;
- GLUhalfEdge *e, *eNext;
-
- for( f = mesh->fHead.next; f != &mesh->fHead; f = fNext ) {
- fNext = f->next;
- memFree( f );
- }
-
- for( v = mesh->vHead.next; v != &mesh->vHead; v = vNext ) {
- vNext = v->next;
- memFree( v );
- }
-
- for( e = mesh->eHead.next; e != &mesh->eHead; e = eNext ) {
- /* One call frees both e and e->Sym (see EdgePair above) */
- eNext = e->next;
- memFree( e );
- }
-
- memFree( mesh );
-}
-
-#endif
-
-#ifndef NDEBUG
-
-/* __gl_meshCheckMesh( mesh ) checks a mesh for self-consistency.
- */
-void __gl_meshCheckMesh( GLUmesh *mesh )
-{
- GLUface *fHead = &mesh->fHead;
- GLUvertex *vHead = &mesh->vHead;
- GLUhalfEdge *eHead = &mesh->eHead;
- GLUface *f, *fPrev;
- GLUvertex *v, *vPrev;
- GLUhalfEdge *e, *ePrev;
-
- fPrev = fHead;
- for( fPrev = fHead ; (f = fPrev->next) != fHead; fPrev = f) {
- assert( f->prev == fPrev );
- e = f->anEdge;
- do {
- assert( e->Sym != e );
- assert( e->Sym->Sym == e );
- assert( e->Lnext->Onext->Sym == e );
- assert( e->Onext->Sym->Lnext == e );
- assert( e->Lface == f );
- e = e->Lnext;
- } while( e != f->anEdge );
- }
- assert( f->prev == fPrev && f->anEdge == NULL && f->data == NULL );
-
- vPrev = vHead;
- for( vPrev = vHead ; (v = vPrev->next) != vHead; vPrev = v) {
- assert( v->prev == vPrev );
- e = v->anEdge;
- do {
- assert( e->Sym != e );
- assert( e->Sym->Sym == e );
- assert( e->Lnext->Onext->Sym == e );
- assert( e->Onext->Sym->Lnext == e );
- assert( e->Org == v );
- e = e->Onext;
- } while( e != v->anEdge );
- }
- assert( v->prev == vPrev && v->anEdge == NULL && v->data == NULL );
-
- ePrev = eHead;
- for( ePrev = eHead ; (e = ePrev->next) != eHead; ePrev = e) {
- assert( e->Sym->next == ePrev->Sym );
- assert( e->Sym != e );
- assert( e->Sym->Sym == e );
- assert( e->Org != NULL );
- assert( e->Dst != NULL );
- assert( e->Lnext->Onext->Sym == e );
- assert( e->Onext->Sym->Lnext == e );
- }
- assert( e->Sym->next == ePrev->Sym
- && e->Sym == &mesh->eHeadSym
- && e->Sym->Sym == e
- && e->Org == NULL && e->Dst == NULL
- && e->Lface == NULL && e->Rface == NULL );
-}
-
-#endif
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#ifndef __mesh_h_
-#define __mesh_h_
-
-#include <GL/glu.h>
-
-typedef struct GLUmesh GLUmesh;
-
-typedef struct GLUvertex GLUvertex;
-typedef struct GLUface GLUface;
-typedef struct GLUhalfEdge GLUhalfEdge;
-
-typedef struct ActiveRegion ActiveRegion; /* Internal data */
-
-/* The mesh structure is similar in spirit, notation, and operations
- * to the "quad-edge" structure (see L. Guibas and J. Stolfi, Primitives
- * for the manipulation of general subdivisions and the computation of
- * Voronoi diagrams, ACM Transactions on Graphics, 4(2):74-123, April 1985).
- * For a simplified description, see the course notes for CS348a,
- * "Mathematical Foundations of Computer Graphics", available at the
- * Stanford bookstore (and taught during the fall quarter).
- * The implementation also borrows a tiny subset of the graph-based approach
- * use in Mantyla's Geometric Work Bench (see M. Mantyla, An Introduction
- * to Sold Modeling, Computer Science Press, Rockville, Maryland, 1988).
- *
- * The fundamental data structure is the "half-edge". Two half-edges
- * go together to make an edge, but they point in opposite directions.
- * Each half-edge has a pointer to its mate (the "symmetric" half-edge Sym),
- * its origin vertex (Org), the face on its left side (Lface), and the
- * adjacent half-edges in the CCW direction around the origin vertex
- * (Onext) and around the left face (Lnext). There is also a "next"
- * pointer for the global edge list (see below).
- *
- * The notation used for mesh navigation:
- * Sym = the mate of a half-edge (same edge, but opposite direction)
- * Onext = edge CCW around origin vertex (keep same origin)
- * Dnext = edge CCW around destination vertex (keep same dest)
- * Lnext = edge CCW around left face (dest becomes new origin)
- * Rnext = edge CCW around right face (origin becomes new dest)
- *
- * "prev" means to substitute CW for CCW in the definitions above.
- *
- * The mesh keeps global lists of all vertices, faces, and edges,
- * stored as doubly-linked circular lists with a dummy header node.
- * The mesh stores pointers to these dummy headers (vHead, fHead, eHead).
- *
- * The circular edge list is special; since half-edges always occur
- * in pairs (e and e->Sym), each half-edge stores a pointer in only
- * one direction. Starting at eHead and following the e->next pointers
- * will visit each *edge* once (ie. e or e->Sym, but not both).
- * e->Sym stores a pointer in the opposite direction, thus it is
- * always true that e->Sym->next->Sym->next == e.
- *
- * Each vertex has a pointer to next and previous vertices in the
- * circular list, and a pointer to a half-edge with this vertex as
- * the origin (NULL if this is the dummy header). There is also a
- * field "data" for client data.
- *
- * Each face has a pointer to the next and previous faces in the
- * circular list, and a pointer to a half-edge with this face as
- * the left face (NULL if this is the dummy header). There is also
- * a field "data" for client data.
- *
- * Note that what we call a "face" is really a loop; faces may consist
- * of more than one loop (ie. not simply connected), but there is no
- * record of this in the data structure. The mesh may consist of
- * several disconnected regions, so it may not be possible to visit
- * the entire mesh by starting at a half-edge and traversing the edge
- * structure.
- *
- * The mesh does NOT support isolated vertices; a vertex is deleted along
- * with its last edge. Similarly when two faces are merged, one of the
- * faces is deleted (see __gl_meshDelete below). For mesh operations,
- * all face (loop) and vertex pointers must not be NULL. However, once
- * mesh manipulation is finished, __gl_MeshZapFace can be used to delete
- * faces of the mesh, one at a time. All external faces can be "zapped"
- * before the mesh is returned to the client; then a NULL face indicates
- * a region which is not part of the output polygon.
- */
-
-struct GLUvertex {
- GLUvertex *next; /* next vertex (never NULL) */
- GLUvertex *prev; /* previous vertex (never NULL) */
- GLUhalfEdge *anEdge; /* a half-edge with this origin */
- void *data; /* client's data */
-
- /* Internal data (keep hidden) */
- GLdouble coords[3]; /* vertex location in 3D */
- GLdouble s, t; /* projection onto the sweep plane */
- long pqHandle; /* to allow deletion from priority queue */
-};
-
-struct GLUface {
- GLUface *next; /* next face (never NULL) */
- GLUface *prev; /* previous face (never NULL) */
- GLUhalfEdge *anEdge; /* a half edge with this left face */
- void *data; /* room for client's data */
-
- /* Internal data (keep hidden) */
- GLUface *trail; /* "stack" for conversion to strips */
- GLboolean marked; /* flag for conversion to strips */
- GLboolean inside; /* this face is in the polygon interior */
-};
-
-struct GLUhalfEdge {
- GLUhalfEdge *next; /* doubly-linked list (prev==Sym->next) */
- GLUhalfEdge *Sym; /* same edge, opposite direction */
- GLUhalfEdge *Onext; /* next edge CCW around origin */
- GLUhalfEdge *Lnext; /* next edge CCW around left face */
- GLUvertex *Org; /* origin vertex (Overtex too long) */
- GLUface *Lface; /* left face */
-
- /* Internal data (keep hidden) */
- ActiveRegion *activeRegion; /* a region with this upper edge (sweep.c) */
- int winding; /* change in winding number when crossing
- from the right face to the left face */
-};
-
-#define Rface Sym->Lface
-#define Dst Sym->Org
-
-#define Oprev Sym->Lnext
-#define Lprev Onext->Sym
-#define Dprev Lnext->Sym
-#define Rprev Sym->Onext
-#define Dnext Rprev->Sym /* 3 pointers */
-#define Rnext Oprev->Sym /* 3 pointers */
-
-
-struct GLUmesh {
- GLUvertex vHead; /* dummy header for vertex list */
- GLUface fHead; /* dummy header for face list */
- GLUhalfEdge eHead; /* dummy header for edge list */
- GLUhalfEdge eHeadSym; /* and its symmetric counterpart */
-};
-
-/* The mesh operations below have three motivations: completeness,
- * convenience, and efficiency. The basic mesh operations are MakeEdge,
- * Splice, and Delete. All the other edge operations can be implemented
- * in terms of these. The other operations are provided for convenience
- * and/or efficiency.
- *
- * When a face is split or a vertex is added, they are inserted into the
- * global list *before* the existing vertex or face (ie. e->Org or e->Lface).
- * This makes it easier to process all vertices or faces in the global lists
- * without worrying about processing the same data twice. As a convenience,
- * when a face is split, the "inside" flag is copied from the old face.
- * Other internal data (v->data, v->activeRegion, f->data, f->marked,
- * f->trail, e->winding) is set to zero.
- *
- * ********************** Basic Edge Operations **************************
- *
- * __gl_meshMakeEdge( mesh ) creates one edge, two vertices, and a loop.
- * The loop (face) consists of the two new half-edges.
- *
- * __gl_meshSplice( eOrg, eDst ) is the basic operation for changing the
- * mesh connectivity and topology. It changes the mesh so that
- * eOrg->Onext <- OLD( eDst->Onext )
- * eDst->Onext <- OLD( eOrg->Onext )
- * where OLD(...) means the value before the meshSplice operation.
- *
- * This can have two effects on the vertex structure:
- * - if eOrg->Org != eDst->Org, the two vertices are merged together
- * - if eOrg->Org == eDst->Org, the origin is split into two vertices
- * In both cases, eDst->Org is changed and eOrg->Org is untouched.
- *
- * Similarly (and independently) for the face structure,
- * - if eOrg->Lface == eDst->Lface, one loop is split into two
- * - if eOrg->Lface != eDst->Lface, two distinct loops are joined into one
- * In both cases, eDst->Lface is changed and eOrg->Lface is unaffected.
- *
- * __gl_meshDelete( eDel ) removes the edge eDel. There are several cases:
- * if (eDel->Lface != eDel->Rface), we join two loops into one; the loop
- * eDel->Lface is deleted. Otherwise, we are splitting one loop into two;
- * the newly created loop will contain eDel->Dst. If the deletion of eDel
- * would create isolated vertices, those are deleted as well.
- *
- * ********************** Other Edge Operations **************************
- *
- * __gl_meshAddEdgeVertex( eOrg ) creates a new edge eNew such that
- * eNew == eOrg->Lnext, and eNew->Dst is a newly created vertex.
- * eOrg and eNew will have the same left face.
- *
- * __gl_meshSplitEdge( eOrg ) splits eOrg into two edges eOrg and eNew,
- * such that eNew == eOrg->Lnext. The new vertex is eOrg->Dst == eNew->Org.
- * eOrg and eNew will have the same left face.
- *
- * __gl_meshConnect( eOrg, eDst ) creates a new edge from eOrg->Dst
- * to eDst->Org, and returns the corresponding half-edge eNew.
- * If eOrg->Lface == eDst->Lface, this splits one loop into two,
- * and the newly created loop is eNew->Lface. Otherwise, two disjoint
- * loops are merged into one, and the loop eDst->Lface is destroyed.
- *
- * ************************ Other Operations *****************************
- *
- * __gl_meshNewMesh() creates a new mesh with no edges, no vertices,
- * and no loops (what we usually call a "face").
- *
- * __gl_meshUnion( mesh1, mesh2 ) forms the union of all structures in
- * both meshes, and returns the new mesh (the old meshes are destroyed).
- *
- * __gl_meshDeleteMesh( mesh ) will free all storage for any valid mesh.
- *
- * __gl_meshZapFace( fZap ) destroys a face and removes it from the
- * global face list. All edges of fZap will have a NULL pointer as their
- * left face. Any edges which also have a NULL pointer as their right face
- * are deleted entirely (along with any isolated vertices this produces).
- * An entire mesh can be deleted by zapping its faces, one at a time,
- * in any order. Zapped faces cannot be used in further mesh operations!
- *
- * __gl_meshCheckMesh( mesh ) checks a mesh for self-consistency.
- */
-
-GLUhalfEdge *__gl_meshMakeEdge( GLUmesh *mesh );
-int __gl_meshSplice( GLUhalfEdge *eOrg, GLUhalfEdge *eDst );
-int __gl_meshDelete( GLUhalfEdge *eDel );
-
-GLUhalfEdge *__gl_meshAddEdgeVertex( GLUhalfEdge *eOrg );
-GLUhalfEdge *__gl_meshSplitEdge( GLUhalfEdge *eOrg );
-GLUhalfEdge *__gl_meshConnect( GLUhalfEdge *eOrg, GLUhalfEdge *eDst );
-
-GLUmesh *__gl_meshNewMesh( void );
-GLUmesh *__gl_meshUnion( GLUmesh *mesh1, GLUmesh *mesh2 );
-void __gl_meshDeleteMesh( GLUmesh *mesh );
-void __gl_meshZapFace( GLUface *fZap );
-
-#ifdef NDEBUG
-#define __gl_meshCheckMesh( mesh )
-#else
-void __gl_meshCheckMesh( GLUmesh *mesh );
-#endif
-
-#endif
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#include "gluos.h"
-#include "mesh.h"
-#include "tess.h"
-#include "normal.h"
-#include <math.h>
-#include <assert.h>
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#define Dot(u,v) (u[0]*v[0] + u[1]*v[1] + u[2]*v[2])
-
-#if 0
-static void Normalize( GLdouble v[3] )
-{
- GLdouble len = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
-
- assert( len > 0 );
- len = sqrt( len );
- v[0] /= len;
- v[1] /= len;
- v[2] /= len;
-}
-#endif
-
-#undef ABS
-#define ABS(x) ((x) < 0 ? -(x) : (x))
-
-static int LongAxis( GLdouble v[3] )
-{
- int i = 0;
-
- if( ABS(v[1]) > ABS(v[0]) ) { i = 1; }
- if( ABS(v[2]) > ABS(v[i]) ) { i = 2; }
- return i;
-}
-
-static void ComputeNormal( GLUtesselator *tess, GLdouble norm[3] )
-{
- GLUvertex *v, *v1, *v2;
- GLdouble c, tLen2, maxLen2;
- GLdouble maxVal[3], minVal[3], d1[3], d2[3], tNorm[3];
- GLUvertex *maxVert[3], *minVert[3];
- GLUvertex *vHead = &tess->mesh->vHead;
- int i;
-
- maxVal[0] = maxVal[1] = maxVal[2] = -2 * GLU_TESS_MAX_COORD;
- minVal[0] = minVal[1] = minVal[2] = 2 * GLU_TESS_MAX_COORD;
-
- for( v = vHead->next; v != vHead; v = v->next ) {
- for( i = 0; i < 3; ++i ) {
- c = v->coords[i];
- if( c < minVal[i] ) { minVal[i] = c; minVert[i] = v; }
- if( c > maxVal[i] ) { maxVal[i] = c; maxVert[i] = v; }
- }
- }
-
- /* Find two vertices separated by at least 1/sqrt(3) of the maximum
- * distance between any two vertices
- */
- i = 0;
- if( maxVal[1] - minVal[1] > maxVal[0] - minVal[0] ) { i = 1; }
- if( maxVal[2] - minVal[2] > maxVal[i] - minVal[i] ) { i = 2; }
- if( minVal[i] >= maxVal[i] ) {
- /* All vertices are the same -- normal doesn't matter */
- norm[0] = 0; norm[1] = 0; norm[2] = 1;
- return;
- }
-
- /* Look for a third vertex which forms the triangle with maximum area
- * (Length of normal == twice the triangle area)
- */
- maxLen2 = 0;
- v1 = minVert[i];
- v2 = maxVert[i];
- d1[0] = v1->coords[0] - v2->coords[0];
- d1[1] = v1->coords[1] - v2->coords[1];
- d1[2] = v1->coords[2] - v2->coords[2];
- for( v = vHead->next; v != vHead; v = v->next ) {
- d2[0] = v->coords[0] - v2->coords[0];
- d2[1] = v->coords[1] - v2->coords[1];
- d2[2] = v->coords[2] - v2->coords[2];
- tNorm[0] = d1[1]*d2[2] - d1[2]*d2[1];
- tNorm[1] = d1[2]*d2[0] - d1[0]*d2[2];
- tNorm[2] = d1[0]*d2[1] - d1[1]*d2[0];
- tLen2 = tNorm[0]*tNorm[0] + tNorm[1]*tNorm[1] + tNorm[2]*tNorm[2];
- if( tLen2 > maxLen2 ) {
- maxLen2 = tLen2;
- norm[0] = tNorm[0];
- norm[1] = tNorm[1];
- norm[2] = tNorm[2];
- }
- }
-
- if( maxLen2 <= 0 ) {
- /* All points lie on a single line -- any decent normal will do */
- norm[0] = norm[1] = norm[2] = 0;
- norm[LongAxis(d1)] = 1;
- }
-}
-
-
-static void CheckOrientation( GLUtesselator *tess )
-{
- GLdouble area;
- GLUface *f, *fHead = &tess->mesh->fHead;
- GLUvertex *v, *vHead = &tess->mesh->vHead;
- GLUhalfEdge *e;
-
- /* When we compute the normal automatically, we choose the orientation
- * so that the sum of the signed areas of all contours is non-negative.
- */
- area = 0;
- for( f = fHead->next; f != fHead; f = f->next ) {
- e = f->anEdge;
- if( e->winding <= 0 ) continue;
- do {
- area += (e->Org->s - e->Dst->s) * (e->Org->t + e->Dst->t);
- e = e->Lnext;
- } while( e != f->anEdge );
- }
- if( area < 0 ) {
- /* Reverse the orientation by flipping all the t-coordinates */
- for( v = vHead->next; v != vHead; v = v->next ) {
- v->t = - v->t;
- }
- tess->tUnit[0] = - tess->tUnit[0];
- tess->tUnit[1] = - tess->tUnit[1];
- tess->tUnit[2] = - tess->tUnit[2];
- }
-}
-
-#ifdef FOR_TRITE_TEST_PROGRAM
-#include <stdlib.h>
-extern int RandomSweep;
-#define S_UNIT_X (RandomSweep ? (2*drand48()-1) : 1.0)
-#define S_UNIT_Y (RandomSweep ? (2*drand48()-1) : 0.0)
-#else
-#if defined(SLANTED_SWEEP)
-/* The "feature merging" is not intended to be complete. There are
- * special cases where edges are nearly parallel to the sweep line
- * which are not implemented. The algorithm should still behave
- * robustly (ie. produce a reasonable tesselation) in the presence
- * of such edges, however it may miss features which could have been
- * merged. We could minimize this effect by choosing the sweep line
- * direction to be something unusual (ie. not parallel to one of the
- * coordinate axes).
- */
-#define S_UNIT_X 0.50941539564955385 /* Pre-normalized */
-#define S_UNIT_Y 0.86052074622010633
-#else
-#define S_UNIT_X 1.0
-#define S_UNIT_Y 0.0
-#endif
-#endif
-
-/* Determine the polygon normal and project vertices onto the plane
- * of the polygon.
- */
-void __gl_projectPolygon( GLUtesselator *tess )
-{
- GLUvertex *v, *vHead = &tess->mesh->vHead;
- GLdouble norm[3];
- GLdouble *sUnit, *tUnit;
- int i, computedNormal = FALSE;
-
- norm[0] = tess->normal[0];
- norm[1] = tess->normal[1];
- norm[2] = tess->normal[2];
- if( norm[0] == 0 && norm[1] == 0 && norm[2] == 0 ) {
- ComputeNormal( tess, norm );
- computedNormal = TRUE;
- }
- sUnit = tess->sUnit;
- tUnit = tess->tUnit;
- i = LongAxis( norm );
-
-#if defined(FOR_TRITE_TEST_PROGRAM) || defined(TRUE_PROJECT)
- /* Choose the initial sUnit vector to be approximately perpendicular
- * to the normal.
- */
- Normalize( norm );
-
- sUnit[i] = 0;
- sUnit[(i+1)%3] = S_UNIT_X;
- sUnit[(i+2)%3] = S_UNIT_Y;
-
- /* Now make it exactly perpendicular */
- w = Dot( sUnit, norm );
- sUnit[0] -= w * norm[0];
- sUnit[1] -= w * norm[1];
- sUnit[2] -= w * norm[2];
- Normalize( sUnit );
-
- /* Choose tUnit so that (sUnit,tUnit,norm) form a right-handed frame */
- tUnit[0] = norm[1]*sUnit[2] - norm[2]*sUnit[1];
- tUnit[1] = norm[2]*sUnit[0] - norm[0]*sUnit[2];
- tUnit[2] = norm[0]*sUnit[1] - norm[1]*sUnit[0];
- Normalize( tUnit );
-#else
- /* Project perpendicular to a coordinate axis -- better numerically */
- sUnit[i] = 0;
- sUnit[(i+1)%3] = S_UNIT_X;
- sUnit[(i+2)%3] = S_UNIT_Y;
-
- tUnit[i] = 0;
- tUnit[(i+1)%3] = (norm[i] > 0) ? -S_UNIT_Y : S_UNIT_Y;
- tUnit[(i+2)%3] = (norm[i] > 0) ? S_UNIT_X : -S_UNIT_X;
-#endif
-
- /* Project the vertices onto the sweep plane */
- for( v = vHead->next; v != vHead; v = v->next ) {
- v->s = Dot( v->coords, sUnit );
- v->t = Dot( v->coords, tUnit );
- }
- if( computedNormal ) {
- CheckOrientation( tess );
- }
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#ifndef __normal_h_
-#define __normal_h_
-
-#include "tess.h"
-
-/* __gl_projectPolygon( tess ) determines the polygon normal
- * and project vertices onto the plane of the polygon.
- */
-void __gl_projectPolygon( GLUtesselator *tess );
-
-#endif
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#include <stddef.h>
-#include <assert.h>
-#include "priorityq-heap.h"
-#include "memalloc.h"
-
-#define INIT_SIZE 32
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifdef FOR_TRITE_TEST_PROGRAM
-#define LEQ(x,y) (*pq->leq)(x,y)
-#else
-/* Violates modularity, but a little faster */
-#include "geom.h"
-#define LEQ(x,y) VertLeq((GLUvertex *)x, (GLUvertex *)y)
-#endif
-
-/* really __gl_pqHeapNewPriorityQ */
-PriorityQ *pqNewPriorityQ( int (*leq)(PQkey key1, PQkey key2) )
-{
- PriorityQ *pq = (PriorityQ *)memAlloc( sizeof( PriorityQ ));
- if (pq == NULL) return NULL;
-
- pq->size = 0;
- pq->max = INIT_SIZE;
- pq->nodes = (PQnode *)memAlloc( (INIT_SIZE + 1) * sizeof(pq->nodes[0]) );
- if (pq->nodes == NULL) {
- memFree(pq);
- return NULL;
- }
-
- pq->handles = (PQhandleElem *)memAlloc( (INIT_SIZE + 1) * sizeof(pq->handles[0]) );
- if (pq->handles == NULL) {
- memFree(pq->nodes);
- memFree(pq);
- return NULL;
- }
-
- pq->initialized = FALSE;
- pq->freeList = 0;
- pq->leq = leq;
-
- pq->nodes[1].handle = 1; /* so that Minimum() returns NULL */
- pq->handles[1].key = NULL;
- return pq;
-}
-
-/* really __gl_pqHeapDeletePriorityQ */
-void pqDeletePriorityQ( PriorityQ *pq )
-{
- memFree( pq->handles );
- memFree( pq->nodes );
- memFree( pq );
-}
-
-
-static void FloatDown( PriorityQ *pq, long curr )
-{
- PQnode *n = pq->nodes;
- PQhandleElem *h = pq->handles;
- PQhandle hCurr, hChild;
- long child;
-
- hCurr = n[curr].handle;
- for( ;; ) {
- child = curr << 1;
- if( child < pq->size && LEQ( h[n[child+1].handle].key,
- h[n[child].handle].key )) {
- ++child;
- }
-
- assert(child <= pq->max);
-
- hChild = n[child].handle;
- if( child > pq->size || LEQ( h[hCurr].key, h[hChild].key )) {
- n[curr].handle = hCurr;
- h[hCurr].node = curr;
- break;
- }
- n[curr].handle = hChild;
- h[hChild].node = curr;
- curr = child;
- }
-}
-
-
-static void FloatUp( PriorityQ *pq, long curr )
-{
- PQnode *n = pq->nodes;
- PQhandleElem *h = pq->handles;
- PQhandle hCurr, hParent;
- long parent;
-
- hCurr = n[curr].handle;
- for( ;; ) {
- parent = curr >> 1;
- hParent = n[parent].handle;
- if( parent == 0 || LEQ( h[hParent].key, h[hCurr].key )) {
- n[curr].handle = hCurr;
- h[hCurr].node = curr;
- break;
- }
- n[curr].handle = hParent;
- h[hParent].node = curr;
- curr = parent;
- }
-}
-
-/* really __gl_pqHeapInit */
-void pqInit( PriorityQ *pq )
-{
- long i;
-
- /* This method of building a heap is O(n), rather than O(n lg n). */
-
- for( i = pq->size; i >= 1; --i ) {
- FloatDown( pq, i );
- }
- pq->initialized = TRUE;
-}
-
-/* really __gl_pqHeapInsert */
-/* returns LONG_MAX iff out of memory */
-PQhandle pqInsert( PriorityQ *pq, PQkey keyNew )
-{
- long curr;
- PQhandle free_handle;
-
- curr = ++ pq->size;
- if( (curr*2) > pq->max ) {
- PQnode *saveNodes= pq->nodes;
- PQhandleElem *saveHandles= pq->handles;
-
- /* If the heap overflows, double its size. */
- pq->max <<= 1;
- pq->nodes = (PQnode *)memRealloc( pq->nodes,
- (size_t)
- ((pq->max + 1) * sizeof( pq->nodes[0] )));
- if (pq->nodes == NULL) {
- pq->nodes = saveNodes; /* restore ptr to free upon return */
- return LONG_MAX;
- }
- pq->handles = (PQhandleElem *)memRealloc( pq->handles,
- (size_t)
- ((pq->max + 1) *
- sizeof( pq->handles[0] )));
- if (pq->handles == NULL) {
- pq->handles = saveHandles; /* restore ptr to free upon return */
- return LONG_MAX;
- }
- }
-
- if( pq->freeList == 0 ) {
- free_handle = curr;
- } else {
- free_handle = pq->freeList;
- pq->freeList = pq->handles[free_handle].node;
- }
-
- pq->nodes[curr].handle = free_handle;
- pq->handles[free_handle].node = curr;
- pq->handles[free_handle].key = keyNew;
-
- if( pq->initialized ) {
- FloatUp( pq, curr );
- }
- assert(free_handle != LONG_MAX);
- return free_handle;
-}
-
-/* really __gl_pqHeapExtractMin */
-PQkey pqExtractMin( PriorityQ *pq )
-{
- PQnode *n = pq->nodes;
- PQhandleElem *h = pq->handles;
- PQhandle hMin = n[1].handle;
- PQkey min = h[hMin].key;
-
- if( pq->size > 0 ) {
- n[1].handle = n[pq->size].handle;
- h[n[1].handle].node = 1;
-
- h[hMin].key = NULL;
- h[hMin].node = pq->freeList;
- pq->freeList = hMin;
-
- if( -- pq->size > 0 ) {
- FloatDown( pq, 1 );
- }
- }
- return min;
-}
-
-/* really __gl_pqHeapDelete */
-void pqDelete( PriorityQ *pq, PQhandle hCurr )
-{
- PQnode *n = pq->nodes;
- PQhandleElem *h = pq->handles;
- long curr;
-
- assert( hCurr >= 1 && hCurr <= pq->max && h[hCurr].key != NULL );
-
- curr = h[hCurr].node;
- n[curr].handle = n[pq->size].handle;
- h[n[curr].handle].node = curr;
-
- if( curr <= -- pq->size ) {
- if( curr <= 1 || LEQ( h[n[curr>>1].handle].key, h[n[curr].handle].key )) {
- FloatDown( pq, curr );
- } else {
- FloatUp( pq, curr );
- }
- }
- h[hCurr].key = NULL;
- h[hCurr].node = pq->freeList;
- pq->freeList = hCurr;
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#ifndef __priorityq_heap_h_
-#define __priorityq_heap_h_
-
-/* Use #define's so that another heap implementation can use this one */
-
-#define PQkey PQHeapKey
-#define PQhandle PQHeapHandle
-#define PriorityQ PriorityQHeap
-
-#define pqNewPriorityQ(leq) __gl_pqHeapNewPriorityQ(leq)
-#define pqDeletePriorityQ(pq) __gl_pqHeapDeletePriorityQ(pq)
-
-/* The basic operations are insertion of a new key (pqInsert),
- * and examination/extraction of a key whose value is minimum
- * (pqMinimum/pqExtractMin). Deletion is also allowed (pqDelete);
- * for this purpose pqInsert returns a "handle" which is supplied
- * as the argument.
- *
- * An initial heap may be created efficiently by calling pqInsert
- * repeatedly, then calling pqInit. In any case pqInit must be called
- * before any operations other than pqInsert are used.
- *
- * If the heap is empty, pqMinimum/pqExtractMin will return a NULL key.
- * This may also be tested with pqIsEmpty.
- */
-#define pqInit(pq) __gl_pqHeapInit(pq)
-#define pqInsert(pq,key) __gl_pqHeapInsert(pq,key)
-#define pqMinimum(pq) __gl_pqHeapMinimum(pq)
-#define pqExtractMin(pq) __gl_pqHeapExtractMin(pq)
-#define pqDelete(pq,handle) __gl_pqHeapDelete(pq,handle)
-#define pqIsEmpty(pq) __gl_pqHeapIsEmpty(pq)
-
-
-/* Since we support deletion the data structure is a little more
- * complicated than an ordinary heap. "nodes" is the heap itself;
- * active nodes are stored in the range 1..pq->size. When the
- * heap exceeds its allocated size (pq->max), its size doubles.
- * The children of node i are nodes 2i and 2i+1.
- *
- * Each node stores an index into an array "handles". Each handle
- * stores a key, plus a pointer back to the node which currently
- * represents that key (ie. nodes[handles[i].node].handle == i).
- */
-
-typedef void *PQkey;
-typedef long PQhandle;
-typedef struct PriorityQ PriorityQ;
-
-typedef struct { PQhandle handle; } PQnode;
-typedef struct { PQkey key; PQhandle node; } PQhandleElem;
-
-struct PriorityQ {
- PQnode *nodes;
- PQhandleElem *handles;
- long size, max;
- PQhandle freeList;
- int initialized;
- int (*leq)(PQkey key1, PQkey key2);
-};
-
-PriorityQ *pqNewPriorityQ( int (*leq)(PQkey key1, PQkey key2) );
-void pqDeletePriorityQ( PriorityQ *pq );
-
-void pqInit( PriorityQ *pq );
-PQhandle pqInsert( PriorityQ *pq, PQkey key );
-PQkey pqExtractMin( PriorityQ *pq );
-void pqDelete( PriorityQ *pq, PQhandle handle );
-
-
-#define __gl_pqHeapMinimum(pq) ((pq)->handles[(pq)->nodes[1].handle].key)
-#define __gl_pqHeapIsEmpty(pq) ((pq)->size == 0)
-
-#endif
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#ifndef __priorityq_sort_h_
-#define __priorityq_sort_h_
-
-#include "priorityq-heap.h"
-
-#undef PQkey
-#undef PQhandle
-#undef PriorityQ
-#undef pqNewPriorityQ
-#undef pqDeletePriorityQ
-#undef pqInit
-#undef pqInsert
-#undef pqMinimum
-#undef pqExtractMin
-#undef pqDelete
-#undef pqIsEmpty
-
-/* Use #define's so that another heap implementation can use this one */
-
-#define PQkey PQSortKey
-#define PQhandle PQSortHandle
-#define PriorityQ PriorityQSort
-
-#define pqNewPriorityQ(leq) __gl_pqSortNewPriorityQ(leq)
-#define pqDeletePriorityQ(pq) __gl_pqSortDeletePriorityQ(pq)
-
-/* The basic operations are insertion of a new key (pqInsert),
- * and examination/extraction of a key whose value is minimum
- * (pqMinimum/pqExtractMin). Deletion is also allowed (pqDelete);
- * for this purpose pqInsert returns a "handle" which is supplied
- * as the argument.
- *
- * An initial heap may be created efficiently by calling pqInsert
- * repeatedly, then calling pqInit. In any case pqInit must be called
- * before any operations other than pqInsert are used.
- *
- * If the heap is empty, pqMinimum/pqExtractMin will return a NULL key.
- * This may also be tested with pqIsEmpty.
- */
-#define pqInit(pq) __gl_pqSortInit(pq)
-#define pqInsert(pq,key) __gl_pqSortInsert(pq,key)
-#define pqMinimum(pq) __gl_pqSortMinimum(pq)
-#define pqExtractMin(pq) __gl_pqSortExtractMin(pq)
-#define pqDelete(pq,handle) __gl_pqSortDelete(pq,handle)
-#define pqIsEmpty(pq) __gl_pqSortIsEmpty(pq)
-
-
-/* Since we support deletion the data structure is a little more
- * complicated than an ordinary heap. "nodes" is the heap itself;
- * active nodes are stored in the range 1..pq->size. When the
- * heap exceeds its allocated size (pq->max), its size doubles.
- * The children of node i are nodes 2i and 2i+1.
- *
- * Each node stores an index into an array "handles". Each handle
- * stores a key, plus a pointer back to the node which currently
- * represents that key (ie. nodes[handles[i].node].handle == i).
- */
-
-typedef PQHeapKey PQkey;
-typedef PQHeapHandle PQhandle;
-typedef struct PriorityQ PriorityQ;
-
-struct PriorityQ {
- PriorityQHeap *heap;
- PQkey *keys;
- PQkey **order;
- PQhandle size, max;
- int initialized;
- int (*leq)(PQkey key1, PQkey key2);
-};
-
-PriorityQ *pqNewPriorityQ( int (*leq)(PQkey key1, PQkey key2) );
-void pqDeletePriorityQ( PriorityQ *pq );
-
-int pqInit( PriorityQ *pq );
-PQhandle pqInsert( PriorityQ *pq, PQkey key );
-PQkey pqExtractMin( PriorityQ *pq );
-void pqDelete( PriorityQ *pq, PQhandle handle );
-
-PQkey pqMinimum( PriorityQ *pq );
-int pqIsEmpty( PriorityQ *pq );
-
-#endif
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#include "gluos.h"
-#include <stddef.h>
-#include <assert.h>
-#include <limits.h> /* LONG_MAX */
-#include "memalloc.h"
-
-/* Include all the code for the regular heap-based queue here. */
-
-#include "priorityq-heap.c"
-
-/* Now redefine all the function names to map to their "Sort" versions. */
-
-#include "priorityq-sort.h"
-
-/* really __gl_pqSortNewPriorityQ */
-PriorityQ *pqNewPriorityQ( int (*leq)(PQkey key1, PQkey key2) )
-{
- PriorityQ *pq = (PriorityQ *)memAlloc( sizeof( PriorityQ ));
- if (pq == NULL) return NULL;
-
- pq->heap = __gl_pqHeapNewPriorityQ( leq );
- if (pq->heap == NULL) {
- memFree(pq);
- return NULL;
- }
-
- pq->keys = (PQHeapKey *)memAlloc( INIT_SIZE * sizeof(pq->keys[0]) );
- if (pq->keys == NULL) {
- __gl_pqHeapDeletePriorityQ(pq->heap);
- memFree(pq);
- return NULL;
- }
-
- pq->size = 0;
- pq->max = INIT_SIZE;
- pq->initialized = FALSE;
- pq->leq = leq;
- return pq;
-}
-
-/* really __gl_pqSortDeletePriorityQ */
-void pqDeletePriorityQ( PriorityQ *pq )
-{
- assert(pq != NULL);
- if (pq->heap != NULL) __gl_pqHeapDeletePriorityQ( pq->heap );
- if (pq->order != NULL) memFree( pq->order );
- if (pq->keys != NULL) memFree( pq->keys );
- memFree( pq );
-}
-
-
-#define LT(x,y) (! LEQ(y,x))
-#define GT(x,y) (! LEQ(x,y))
-#define Swap(a,b) do{PQkey *tmp = *a; *a = *b; *b = tmp;}while(0)
-
-/* really __gl_pqSortInit */
-int pqInit( PriorityQ *pq )
-{
- PQkey **p, **r, **i, **j, *piv;
- struct { PQkey **p, **r; } Stack[50], *top = Stack;
- unsigned long seed = 2016473283;
-
- /* Create an array of indirect pointers to the keys, so that we
- * the handles we have returned are still valid.
- */
-/*
- pq->order = (PQHeapKey **)memAlloc( (size_t)
- (pq->size * sizeof(pq->order[0])) );
-*/
- pq->order = (PQHeapKey **)memAlloc( (size_t)
- ((pq->size+1) * sizeof(pq->order[0])) );
-/* the previous line is a patch to compensate for the fact that IBM */
-/* machines return a null on a malloc of zero bytes (unlike SGI), */
-/* so we have to put in this defense to guard against a memory */
-/* fault four lines down. from fossum@austin.ibm.com. */
- if (pq->order == NULL) return 0;
-
- p = pq->order;
- r = p + pq->size - 1;
- for( piv = pq->keys, i = p; i <= r; ++piv, ++i ) {
- *i = piv;
- }
-
- /* Sort the indirect pointers in descending order,
- * using randomized Quicksort
- */
- top->p = p; top->r = r; ++top;
- while( --top >= Stack ) {
- p = top->p;
- r = top->r;
- while( r > p + 10 ) {
- seed = seed * 1539415821 + 1;
- i = p + seed % (r - p + 1);
- piv = *i;
- *i = *p;
- *p = piv;
- i = p - 1;
- j = r + 1;
- do {
- do { ++i; } while( GT( **i, *piv ));
- do { --j; } while( LT( **j, *piv ));
- Swap( i, j );
- } while( i < j );
- Swap( i, j ); /* Undo last swap */
- if( i - p < r - j ) {
- top->p = j+1; top->r = r; ++top;
- r = i-1;
- } else {
- top->p = p; top->r = i-1; ++top;
- p = j+1;
- }
- }
- /* Insertion sort small lists */
- for( i = p+1; i <= r; ++i ) {
- piv = *i;
- for( j = i; j > p && LT( **(j-1), *piv ); --j ) {
- *j = *(j-1);
- }
- *j = piv;
- }
- }
- pq->max = pq->size;
- pq->initialized = TRUE;
- __gl_pqHeapInit( pq->heap ); /* always succeeds */
-
-#ifndef NDEBUG
- p = pq->order;
- r = p + pq->size - 1;
- for( i = p; i < r; ++i ) {
- assert( LEQ( **(i+1), **i ));
- }
-#endif
-
- return 1;
-}
-
-/* really __gl_pqSortInsert */
-/* returns LONG_MAX iff out of memory */
-PQhandle pqInsert( PriorityQ *pq, PQkey keyNew )
-{
- long curr;
-
- if( pq->initialized ) {
- return __gl_pqHeapInsert( pq->heap, keyNew );
- }
- curr = pq->size;
- if( ++ pq->size >= pq->max ) {
- PQkey *saveKey= pq->keys;
-
- /* If the heap overflows, double its size. */
- pq->max <<= 1;
- pq->keys = (PQHeapKey *)memRealloc( pq->keys,
- (size_t)
- (pq->max * sizeof( pq->keys[0] )));
- if (pq->keys == NULL) {
- pq->keys = saveKey; /* restore ptr to free upon return */
- return LONG_MAX;
- }
- }
- assert(curr != LONG_MAX);
- pq->keys[curr] = keyNew;
-
- /* Negative handles index the sorted array. */
- return -(curr+1);
-}
-
-/* really __gl_pqSortExtractMin */
-PQkey pqExtractMin( PriorityQ *pq )
-{
- PQkey sortMin, heapMin;
-
- if( pq->size == 0 ) {
- return __gl_pqHeapExtractMin( pq->heap );
- }
- sortMin = *(pq->order[pq->size-1]);
- if( ! __gl_pqHeapIsEmpty( pq->heap )) {
- heapMin = __gl_pqHeapMinimum( pq->heap );
- if( LEQ( heapMin, sortMin )) {
- return __gl_pqHeapExtractMin( pq->heap );
- }
- }
- do {
- -- pq->size;
- } while( pq->size > 0 && *(pq->order[pq->size-1]) == NULL );
- return sortMin;
-}
-
-/* really __gl_pqSortMinimum */
-PQkey pqMinimum( PriorityQ *pq )
-{
- PQkey sortMin, heapMin;
-
- if( pq->size == 0 ) {
- return __gl_pqHeapMinimum( pq->heap );
- }
- sortMin = *(pq->order[pq->size-1]);
- if( ! __gl_pqHeapIsEmpty( pq->heap )) {
- heapMin = __gl_pqHeapMinimum( pq->heap );
- if( LEQ( heapMin, sortMin )) {
- return heapMin;
- }
- }
- return sortMin;
-}
-
-/* really __gl_pqSortIsEmpty */
-int pqIsEmpty( PriorityQ *pq )
-{
- return (pq->size == 0) && __gl_pqHeapIsEmpty( pq->heap );
-}
-
-/* really __gl_pqSortDelete */
-void pqDelete( PriorityQ *pq, PQhandle curr )
-{
- if( curr >= 0 ) {
- __gl_pqHeapDelete( pq->heap, curr );
- return;
- }
- curr = -(curr+1);
- assert( curr < pq->max && pq->keys[curr] != NULL );
-
- pq->keys[curr] = NULL;
- while( pq->size > 0 && *(pq->order[pq->size-1]) == NULL ) {
- -- pq->size;
- }
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#ifndef __priorityq_sort_h_
-#define __priorityq_sort_h_
-
-#include "priorityq-heap.h"
-
-#undef PQkey
-#undef PQhandle
-#undef PriorityQ
-#undef pqNewPriorityQ
-#undef pqDeletePriorityQ
-#undef pqInit
-#undef pqInsert
-#undef pqMinimum
-#undef pqExtractMin
-#undef pqDelete
-#undef pqIsEmpty
-
-/* Use #define's so that another heap implementation can use this one */
-
-#define PQkey PQSortKey
-#define PQhandle PQSortHandle
-#define PriorityQ PriorityQSort
-
-#define pqNewPriorityQ(leq) __gl_pqSortNewPriorityQ(leq)
-#define pqDeletePriorityQ(pq) __gl_pqSortDeletePriorityQ(pq)
-
-/* The basic operations are insertion of a new key (pqInsert),
- * and examination/extraction of a key whose value is minimum
- * (pqMinimum/pqExtractMin). Deletion is also allowed (pqDelete);
- * for this purpose pqInsert returns a "handle" which is supplied
- * as the argument.
- *
- * An initial heap may be created efficiently by calling pqInsert
- * repeatedly, then calling pqInit. In any case pqInit must be called
- * before any operations other than pqInsert are used.
- *
- * If the heap is empty, pqMinimum/pqExtractMin will return a NULL key.
- * This may also be tested with pqIsEmpty.
- */
-#define pqInit(pq) __gl_pqSortInit(pq)
-#define pqInsert(pq,key) __gl_pqSortInsert(pq,key)
-#define pqMinimum(pq) __gl_pqSortMinimum(pq)
-#define pqExtractMin(pq) __gl_pqSortExtractMin(pq)
-#define pqDelete(pq,handle) __gl_pqSortDelete(pq,handle)
-#define pqIsEmpty(pq) __gl_pqSortIsEmpty(pq)
-
-
-/* Since we support deletion the data structure is a little more
- * complicated than an ordinary heap. "nodes" is the heap itself;
- * active nodes are stored in the range 1..pq->size. When the
- * heap exceeds its allocated size (pq->max), its size doubles.
- * The children of node i are nodes 2i and 2i+1.
- *
- * Each node stores an index into an array "handles". Each handle
- * stores a key, plus a pointer back to the node which currently
- * represents that key (ie. nodes[handles[i].node].handle == i).
- */
-
-typedef PQHeapKey PQkey;
-typedef PQHeapHandle PQhandle;
-typedef struct PriorityQ PriorityQ;
-
-struct PriorityQ {
- PriorityQHeap *heap;
- PQkey *keys;
- PQkey **order;
- PQhandle size, max;
- int initialized;
- int (*leq)(PQkey key1, PQkey key2);
-};
-
-PriorityQ *pqNewPriorityQ( int (*leq)(PQkey key1, PQkey key2) );
-void pqDeletePriorityQ( PriorityQ *pq );
-
-int pqInit( PriorityQ *pq );
-PQhandle pqInsert( PriorityQ *pq, PQkey key );
-PQkey pqExtractMin( PriorityQ *pq );
-void pqDelete( PriorityQ *pq, PQhandle handle );
-
-PQkey pqMinimum( PriorityQ *pq );
-int pqIsEmpty( PriorityQ *pq );
-
-#endif
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#include "gluos.h"
-#include <assert.h>
-#include <stddef.h>
-#include "mesh.h"
-#include "tess.h"
-#include "render.h"
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-/* This structure remembers the information we need about a primitive
- * to be able to render it later, once we have determined which
- * primitive is able to use the most triangles.
- */
-struct FaceCount {
- long size; /* number of triangles used */
- GLUhalfEdge *eStart; /* edge where this primitive starts */
- void (*render)(GLUtesselator *, GLUhalfEdge *, long);
- /* routine to render this primitive */
-};
-
-static struct FaceCount MaximumFan( GLUhalfEdge *eOrig );
-static struct FaceCount MaximumStrip( GLUhalfEdge *eOrig );
-
-static void RenderFan( GLUtesselator *tess, GLUhalfEdge *eStart, long size );
-static void RenderStrip( GLUtesselator *tess, GLUhalfEdge *eStart, long size );
-static void RenderTriangle( GLUtesselator *tess, GLUhalfEdge *eStart,
- long size );
-
-static void RenderMaximumFaceGroup( GLUtesselator *tess, GLUface *fOrig );
-static void RenderLonelyTriangles( GLUtesselator *tess, GLUface *head );
-
-
-
-/************************ Strips and Fans decomposition ******************/
-
-/* __gl_renderMesh( tess, mesh ) takes a mesh and breaks it into triangle
- * fans, strips, and separate triangles. A substantial effort is made
- * to use as few rendering primitives as possible (ie. to make the fans
- * and strips as large as possible).
- *
- * The rendering output is provided as callbacks (see the api).
- */
-void __gl_renderMesh( GLUtesselator *tess, GLUmesh *mesh )
-{
- GLUface *f;
-
- /* Make a list of separate triangles so we can render them all at once */
- tess->lonelyTriList = NULL;
-
- for( f = mesh->fHead.next; f != &mesh->fHead; f = f->next ) {
- f->marked = FALSE;
- }
- for( f = mesh->fHead.next; f != &mesh->fHead; f = f->next ) {
-
- /* We examine all faces in an arbitrary order. Whenever we find
- * an unprocessed face F, we output a group of faces including F
- * whose size is maximum.
- */
- if( f->inside && ! f->marked ) {
- RenderMaximumFaceGroup( tess, f );
- assert( f->marked );
- }
- }
- if( tess->lonelyTriList != NULL ) {
- RenderLonelyTriangles( tess, tess->lonelyTriList );
- tess->lonelyTriList = NULL;
- }
-}
-
-
-static void RenderMaximumFaceGroup( GLUtesselator *tess, GLUface *fOrig )
-{
- /* We want to find the largest triangle fan or strip of unmarked faces
- * which includes the given face fOrig. There are 3 possible fans
- * passing through fOrig (one centered at each vertex), and 3 possible
- * strips (one for each CCW permutation of the vertices). Our strategy
- * is to try all of these, and take the primitive which uses the most
- * triangles (a greedy approach).
- */
- GLUhalfEdge *e = fOrig->anEdge;
- struct FaceCount max, newFace;
-
- max.size = 1;
- max.eStart = e;
- max.render = &RenderTriangle;
-
- if( ! tess->flagBoundary ) {
- newFace = MaximumFan( e ); if( newFace.size > max.size ) { max = newFace; }
- newFace = MaximumFan( e->Lnext ); if( newFace.size > max.size ) { max = newFace; }
- newFace = MaximumFan( e->Lprev ); if( newFace.size > max.size ) { max = newFace; }
-
- newFace = MaximumStrip( e ); if( newFace.size > max.size ) { max = newFace; }
- newFace = MaximumStrip( e->Lnext ); if( newFace.size > max.size ) { max = newFace; }
- newFace = MaximumStrip( e->Lprev ); if( newFace.size > max.size ) { max = newFace; }
- }
- (*(max.render))( tess, max.eStart, max.size );
-}
-
-
-/* Macros which keep track of faces we have marked temporarily, and allow
- * us to backtrack when necessary. With triangle fans, this is not
- * really necessary, since the only awkward case is a loop of triangles
- * around a single origin vertex. However with strips the situation is
- * more complicated, and we need a general tracking method like the
- * one here.
- */
-#define Marked(f) (! (f)->inside || (f)->marked)
-
-#define AddToTrail(f,t) ((f)->trail = (t), (t) = (f), (f)->marked = TRUE)
-
-#define FreeTrail(t) do { \
- while( (t) != NULL ) { \
- (t)->marked = FALSE; t = (t)->trail; \
- } \
- } while(0) /* absorb trailing semicolon */
-
-
-
-static struct FaceCount MaximumFan( GLUhalfEdge *eOrig )
-{
- /* eOrig->Lface is the face we want to render. We want to find the size
- * of a maximal fan around eOrig->Org. To do this we just walk around
- * the origin vertex as far as possible in both directions.
- */
- struct FaceCount newFace = { 0, NULL, &RenderFan };
- GLUface *trail = NULL;
- GLUhalfEdge *e;
-
- for( e = eOrig; ! Marked( e->Lface ); e = e->Onext ) {
- AddToTrail( e->Lface, trail );
- ++newFace.size;
- }
- for( e = eOrig; ! Marked( e->Rface ); e = e->Oprev ) {
- AddToTrail( e->Rface, trail );
- ++newFace.size;
- }
- newFace.eStart = e;
- /*LINTED*/
- FreeTrail( trail );
- return newFace;
-}
-
-
-#define IsEven(n) (((n) & 1) == 0)
-
-static struct FaceCount MaximumStrip( GLUhalfEdge *eOrig )
-{
- /* Here we are looking for a maximal strip that contains the vertices
- * eOrig->Org, eOrig->Dst, eOrig->Lnext->Dst (in that order or the
- * reverse, such that all triangles are oriented CCW).
- *
- * Again we walk forward and backward as far as possible. However for
- * strips there is a twist: to get CCW orientations, there must be
- * an *even* number of triangles in the strip on one side of eOrig.
- * We walk the strip starting on a side with an even number of triangles;
- * if both side have an odd number, we are forced to shorten one side.
- */
- struct FaceCount newFace = { 0, NULL, &RenderStrip };
- long headSize = 0, tailSize = 0;
- GLUface *trail = NULL;
- GLUhalfEdge *e, *eTail, *eHead;
-
- for( e = eOrig; ! Marked( e->Lface ); ++tailSize, e = e->Onext ) {
- AddToTrail( e->Lface, trail );
- ++tailSize;
- e = e->Dprev;
- if( Marked( e->Lface )) break;
- AddToTrail( e->Lface, trail );
- }
- eTail = e;
-
- for( e = eOrig; ! Marked( e->Rface ); ++headSize, e = e->Dnext ) {
- AddToTrail( e->Rface, trail );
- ++headSize;
- e = e->Oprev;
- if( Marked( e->Rface )) break;
- AddToTrail( e->Rface, trail );
- }
- eHead = e;
-
- newFace.size = tailSize + headSize;
- if( IsEven( tailSize )) {
- newFace.eStart = eTail->Sym;
- } else if( IsEven( headSize )) {
- newFace.eStart = eHead;
- } else {
- /* Both sides have odd length, we must shorten one of them. In fact,
- * we must start from eHead to guarantee inclusion of eOrig->Lface.
- */
- --newFace.size;
- newFace.eStart = eHead->Onext;
- }
- /*LINTED*/
- FreeTrail( trail );
- return newFace;
-}
-
-
-static void RenderTriangle( GLUtesselator *tess, GLUhalfEdge *e, long size )
-{
- /* Just add the triangle to a triangle list, so we can render all
- * the separate triangles at once.
- */
- assert( size == 1 );
- AddToTrail( e->Lface, tess->lonelyTriList );
-}
-
-
-static void RenderLonelyTriangles( GLUtesselator *tess, GLUface *f )
-{
- /* Now we render all the separate triangles which could not be
- * grouped into a triangle fan or strip.
- */
- GLUhalfEdge *e;
- int newState;
- int edgeState = -1; /* force edge state output for first vertex */
-
- CALL_BEGIN_OR_BEGIN_DATA( GL_TRIANGLES );
-
- for( ; f != NULL; f = f->trail ) {
- /* Loop once for each edge (there will always be 3 edges) */
-
- e = f->anEdge;
- do {
- if( tess->flagBoundary ) {
- /* Set the "edge state" to TRUE just before we output the
- * first vertex of each edge on the polygon boundary.
- */
- newState = ! e->Rface->inside;
- if( edgeState != newState ) {
- edgeState = newState;
- CALL_EDGE_FLAG_OR_EDGE_FLAG_DATA( edgeState );
- }
- }
- CALL_VERTEX_OR_VERTEX_DATA( e->Org->data );
-
- e = e->Lnext;
- } while( e != f->anEdge );
- }
- CALL_END_OR_END_DATA();
-}
-
-
-static void RenderFan( GLUtesselator *tess, GLUhalfEdge *e, long size )
-{
- /* Render as many CCW triangles as possible in a fan starting from
- * edge "e". The fan *should* contain exactly "size" triangles
- * (otherwise we've goofed up somewhere).
- */
- CALL_BEGIN_OR_BEGIN_DATA( GL_TRIANGLE_FAN );
- CALL_VERTEX_OR_VERTEX_DATA( e->Org->data );
- CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data );
-
- while( ! Marked( e->Lface )) {
- e->Lface->marked = TRUE;
- --size;
- e = e->Onext;
- CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data );
- }
-
- assert( size == 0 );
- CALL_END_OR_END_DATA();
-}
-
-
-static void RenderStrip( GLUtesselator *tess, GLUhalfEdge *e, long size )
-{
- /* Render as many CCW triangles as possible in a strip starting from
- * edge "e". The strip *should* contain exactly "size" triangles
- * (otherwise we've goofed up somewhere).
- */
- CALL_BEGIN_OR_BEGIN_DATA( GL_TRIANGLE_STRIP );
- CALL_VERTEX_OR_VERTEX_DATA( e->Org->data );
- CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data );
-
- while( ! Marked( e->Lface )) {
- e->Lface->marked = TRUE;
- --size;
- e = e->Dprev;
- CALL_VERTEX_OR_VERTEX_DATA( e->Org->data );
- if( Marked( e->Lface )) break;
-
- e->Lface->marked = TRUE;
- --size;
- e = e->Onext;
- CALL_VERTEX_OR_VERTEX_DATA( e->Dst->data );
- }
-
- assert( size == 0 );
- CALL_END_OR_END_DATA();
-}
-
-
-/************************ Boundary contour decomposition ******************/
-
-/* __gl_renderBoundary( tess, mesh ) takes a mesh, and outputs one
- * contour for each face marked "inside". The rendering output is
- * provided as callbacks (see the api).
- */
-void __gl_renderBoundary( GLUtesselator *tess, GLUmesh *mesh )
-{
- GLUface *f;
- GLUhalfEdge *e;
-
- for( f = mesh->fHead.next; f != &mesh->fHead; f = f->next ) {
- if( f->inside ) {
- CALL_BEGIN_OR_BEGIN_DATA( GL_LINE_LOOP );
- e = f->anEdge;
- do {
- CALL_VERTEX_OR_VERTEX_DATA( e->Org->data );
- e = e->Lnext;
- } while( e != f->anEdge );
- CALL_END_OR_END_DATA();
- }
- }
-}
-
-
-/************************ Quick-and-dirty decomposition ******************/
-
-#define SIGN_INCONSISTENT 2
-
-static int ComputeNormal( GLUtesselator *tess, GLdouble norm[3], int check )
-/*
- * If check==FALSE, we compute the polygon normal and place it in norm[].
- * If check==TRUE, we check that each triangle in the fan from v0 has a
- * consistent orientation with respect to norm[]. If triangles are
- * consistently oriented CCW, return 1; if CW, return -1; if all triangles
- * are degenerate return 0; otherwise (no consistent orientation) return
- * SIGN_INCONSISTENT.
- */
-{
- CachedVertex *v0 = tess->cache;
- CachedVertex *vn = v0 + tess->cacheCount;
- CachedVertex *vc;
- GLdouble dot, xc, yc, zc, xp, yp, zp, n[3];
- int sign = 0;
-
- /* Find the polygon normal. It is important to get a reasonable
- * normal even when the polygon is self-intersecting (eg. a bowtie).
- * Otherwise, the computed normal could be very tiny, but perpendicular
- * to the true plane of the polygon due to numerical noise. Then all
- * the triangles would appear to be degenerate and we would incorrectly
- * decompose the polygon as a fan (or simply not render it at all).
- *
- * We use a sum-of-triangles normal algorithm rather than the more
- * efficient sum-of-trapezoids method (used in CheckOrientation()
- * in normal.c). This lets us explicitly reverse the signed area
- * of some triangles to get a reasonable normal in the self-intersecting
- * case.
- */
- if( ! check ) {
- norm[0] = norm[1] = norm[2] = 0.0;
- }
-
- vc = v0 + 1;
- xc = vc->coords[0] - v0->coords[0];
- yc = vc->coords[1] - v0->coords[1];
- zc = vc->coords[2] - v0->coords[2];
- while( ++vc < vn ) {
- xp = xc; yp = yc; zp = zc;
- xc = vc->coords[0] - v0->coords[0];
- yc = vc->coords[1] - v0->coords[1];
- zc = vc->coords[2] - v0->coords[2];
-
- /* Compute (vp - v0) cross (vc - v0) */
- n[0] = yp*zc - zp*yc;
- n[1] = zp*xc - xp*zc;
- n[2] = xp*yc - yp*xc;
-
- dot = n[0]*norm[0] + n[1]*norm[1] + n[2]*norm[2];
- if( ! check ) {
- /* Reverse the contribution of back-facing triangles to get
- * a reasonable normal for self-intersecting polygons (see above)
- */
- if( dot >= 0 ) {
- norm[0] += n[0]; norm[1] += n[1]; norm[2] += n[2];
- } else {
- norm[0] -= n[0]; norm[1] -= n[1]; norm[2] -= n[2];
- }
- } else if( dot != 0 ) {
- /* Check the new orientation for consistency with previous triangles */
- if( dot > 0 ) {
- if( sign < 0 ) return SIGN_INCONSISTENT;
- sign = 1;
- } else {
- if( sign > 0 ) return SIGN_INCONSISTENT;
- sign = -1;
- }
- }
- }
- return sign;
-}
-
-/* __gl_renderCache( tess ) takes a single contour and tries to render it
- * as a triangle fan. This handles convex polygons, as well as some
- * non-convex polygons if we get lucky.
- *
- * Returns TRUE if the polygon was successfully rendered. The rendering
- * output is provided as callbacks (see the api).
- */
-GLboolean __gl_renderCache( GLUtesselator *tess )
-{
- CachedVertex *v0 = tess->cache;
- CachedVertex *vn = v0 + tess->cacheCount;
- CachedVertex *vc;
- GLdouble norm[3];
- int sign;
-
- if( tess->cacheCount < 3 ) {
- /* Degenerate contour -- no output */
- return TRUE;
- }
-
- norm[0] = tess->normal[0];
- norm[1] = tess->normal[1];
- norm[2] = tess->normal[2];
- if( norm[0] == 0 && norm[1] == 0 && norm[2] == 0 ) {
- ComputeNormal( tess, norm, FALSE );
- }
-
- sign = ComputeNormal( tess, norm, TRUE );
- if( sign == SIGN_INCONSISTENT ) {
- /* Fan triangles did not have a consistent orientation */
- return FALSE;
- }
- if( sign == 0 ) {
- /* All triangles were degenerate */
- return TRUE;
- }
-
- /* Make sure we do the right thing for each winding rule */
- switch( tess->windingRule ) {
- case GLU_TESS_WINDING_ODD:
- case GLU_TESS_WINDING_NONZERO:
- break;
- case GLU_TESS_WINDING_POSITIVE:
- if( sign < 0 ) return TRUE;
- break;
- case GLU_TESS_WINDING_NEGATIVE:
- if( sign > 0 ) return TRUE;
- break;
- case GLU_TESS_WINDING_ABS_GEQ_TWO:
- return TRUE;
- }
-
- CALL_BEGIN_OR_BEGIN_DATA( tess->boundaryOnly ? GL_LINE_LOOP
- : (tess->cacheCount > 3) ? GL_TRIANGLE_FAN
- : GL_TRIANGLES );
-
- CALL_VERTEX_OR_VERTEX_DATA( v0->data );
- if( sign > 0 ) {
- for( vc = v0+1; vc < vn; ++vc ) {
- CALL_VERTEX_OR_VERTEX_DATA( vc->data );
- }
- } else {
- for( vc = vn-1; vc > v0; --vc ) {
- CALL_VERTEX_OR_VERTEX_DATA( vc->data );
- }
- }
- CALL_END_OR_END_DATA();
- return TRUE;
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#ifndef __render_h_
-#define __render_h_
-
-#include "mesh.h"
-
-/* __gl_renderMesh( tess, mesh ) takes a mesh and breaks it into triangle
- * fans, strips, and separate triangles. A substantial effort is made
- * to use as few rendering primitives as possible (ie. to make the fans
- * and strips as large as possible).
- *
- * The rendering output is provided as callbacks (see the api).
- */
-void __gl_renderMesh( GLUtesselator *tess, GLUmesh *mesh );
-void __gl_renderBoundary( GLUtesselator *tess, GLUmesh *mesh );
-
-GLboolean __gl_renderCache( GLUtesselator *tess );
-
-#endif
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#include "gluos.h"
-#include <assert.h>
-#include <stddef.h>
-#include <setjmp.h> /* longjmp */
-#include <limits.h> /* LONG_MAX */
-
-#include "mesh.h"
-#include "geom.h"
-#include "tess.h"
-#include "dict.h"
-#include "priorityq.h"
-#include "memalloc.h"
-#include "sweep.h"
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifdef FOR_TRITE_TEST_PROGRAM
-extern void DebugEvent( GLUtesselator *tess );
-#else
-#define DebugEvent( tess )
-#endif
-
-/*
- * Invariants for the Edge Dictionary.
- * - each pair of adjacent edges e2=Succ(e1) satisfies EdgeLeq(e1,e2)
- * at any valid location of the sweep event
- * - if EdgeLeq(e2,e1) as well (at any valid sweep event), then e1 and e2
- * share a common endpoint
- * - for each e, e->Dst has been processed, but not e->Org
- * - each edge e satisfies VertLeq(e->Dst,event) && VertLeq(event,e->Org)
- * where "event" is the current sweep line event.
- * - no edge e has zero length
- *
- * Invariants for the Mesh (the processed portion).
- * - the portion of the mesh left of the sweep line is a planar graph,
- * ie. there is *some* way to embed it in the plane
- * - no processed edge has zero length
- * - no two processed vertices have identical coordinates
- * - each "inside" region is monotone, ie. can be broken into two chains
- * of monotonically increasing vertices according to VertLeq(v1,v2)
- * - a non-invariant: these chains may intersect (very slightly)
- *
- * Invariants for the Sweep.
- * - if none of the edges incident to the event vertex have an activeRegion
- * (ie. none of these edges are in the edge dictionary), then the vertex
- * has only right-going edges.
- * - if an edge is marked "fixUpperEdge" (it is a temporary edge introduced
- * by ConnectRightVertex), then it is the only right-going edge from
- * its associated vertex. (This says that these edges exist only
- * when it is necessary.)
- */
-
-#undef MAX
-#undef MIN
-#define MAX(x,y) ((x) >= (y) ? (x) : (y))
-#define MIN(x,y) ((x) <= (y) ? (x) : (y))
-
-/* When we merge two edges into one, we need to compute the combined
- * winding of the new edge.
- */
-#define AddWinding(eDst,eSrc) (eDst->winding += eSrc->winding, \
- eDst->Sym->winding += eSrc->Sym->winding)
-
-static void SweepEvent( GLUtesselator *tess, GLUvertex *vEvent );
-static void WalkDirtyRegions( GLUtesselator *tess, ActiveRegion *regUp );
-static int CheckForRightSplice( GLUtesselator *tess, ActiveRegion *regUp );
-
-static int EdgeLeq( GLUtesselator *tess, ActiveRegion *reg1,
- ActiveRegion *reg2 )
-/*
- * Both edges must be directed from right to left (this is the canonical
- * direction for the upper edge of each region).
- *
- * The strategy is to evaluate a "t" value for each edge at the
- * current sweep line position, given by tess->event. The calculations
- * are designed to be very stable, but of course they are not perfect.
- *
- * Special case: if both edge destinations are at the sweep event,
- * we sort the edges by slope (they would otherwise compare equally).
- */
-{
- GLUvertex *event = tess->event;
- GLUhalfEdge *e1, *e2;
- GLdouble t1, t2;
-
- e1 = reg1->eUp;
- e2 = reg2->eUp;
-
- if( e1->Dst == event ) {
- if( e2->Dst == event ) {
- /* Two edges right of the sweep line which meet at the sweep event.
- * Sort them by slope.
- */
- if( VertLeq( e1->Org, e2->Org )) {
- return EdgeSign( e2->Dst, e1->Org, e2->Org ) <= 0;
- }
- return EdgeSign( e1->Dst, e2->Org, e1->Org ) >= 0;
- }
- return EdgeSign( e2->Dst, event, e2->Org ) <= 0;
- }
- if( e2->Dst == event ) {
- return EdgeSign( e1->Dst, event, e1->Org ) >= 0;
- }
-
- /* General case - compute signed distance *from* e1, e2 to event */
- t1 = EdgeEval( e1->Dst, event, e1->Org );
- t2 = EdgeEval( e2->Dst, event, e2->Org );
- return (t1 >= t2);
-}
-
-
-static void DeleteRegion( GLUtesselator *tess, ActiveRegion *reg )
-{
- if( reg->fixUpperEdge ) {
- /* It was created with zero winding number, so it better be
- * deleted with zero winding number (ie. it better not get merged
- * with a real edge).
- */
- assert( reg->eUp->winding == 0 );
- }
- reg->eUp->activeRegion = NULL;
- dictDelete( tess->dict, reg->nodeUp ); /* __gl_dictListDelete */
- memFree( reg );
-}
-
-
-static int FixUpperEdge( ActiveRegion *reg, GLUhalfEdge *newEdge )
-/*
- * Replace an upper edge which needs fixing (see ConnectRightVertex).
- */
-{
- assert( reg->fixUpperEdge );
- if ( !__gl_meshDelete( reg->eUp ) ) return 0;
- reg->fixUpperEdge = FALSE;
- reg->eUp = newEdge;
- newEdge->activeRegion = reg;
-
- return 1;
-}
-
-static ActiveRegion *TopLeftRegion( ActiveRegion *reg )
-{
- GLUvertex *org = reg->eUp->Org;
- GLUhalfEdge *e;
-
- /* Find the region above the uppermost edge with the same origin */
- do {
- reg = RegionAbove( reg );
- } while( reg->eUp->Org == org );
-
- /* If the edge above was a temporary edge introduced by ConnectRightVertex,
- * now is the time to fix it.
- */
- if( reg->fixUpperEdge ) {
- e = __gl_meshConnect( RegionBelow(reg)->eUp->Sym, reg->eUp->Lnext );
- if (e == NULL) return NULL;
- if ( !FixUpperEdge( reg, e ) ) return NULL;
- reg = RegionAbove( reg );
- }
- return reg;
-}
-
-static ActiveRegion *TopRightRegion( ActiveRegion *reg )
-{
- GLUvertex *dst = reg->eUp->Dst;
-
- /* Find the region above the uppermost edge with the same destination */
- do {
- reg = RegionAbove( reg );
- } while( reg->eUp->Dst == dst );
- return reg;
-}
-
-static ActiveRegion *AddRegionBelow( GLUtesselator *tess,
- ActiveRegion *regAbove,
- GLUhalfEdge *eNewUp )
-/*
- * Add a new active region to the sweep line, *somewhere* below "regAbove"
- * (according to where the new edge belongs in the sweep-line dictionary).
- * The upper edge of the new region will be "eNewUp".
- * Winding number and "inside" flag are not updated.
- */
-{
- ActiveRegion *regNew = (ActiveRegion *)memAlloc( sizeof( ActiveRegion ));
- if (regNew == NULL) longjmp(tess->env,1);
-
- regNew->eUp = eNewUp;
- /* __gl_dictListInsertBefore */
- regNew->nodeUp = dictInsertBefore( tess->dict, regAbove->nodeUp, regNew );
- if (regNew->nodeUp == NULL) longjmp(tess->env,1);
- regNew->fixUpperEdge = FALSE;
- regNew->sentinel = FALSE;
- regNew->dirty = FALSE;
-
- eNewUp->activeRegion = regNew;
- return regNew;
-}
-
-static GLboolean IsWindingInside( GLUtesselator *tess, int n )
-{
- switch( tess->windingRule ) {
- case GLU_TESS_WINDING_ODD:
- return (n & 1);
- case GLU_TESS_WINDING_NONZERO:
- return (n != 0);
- case GLU_TESS_WINDING_POSITIVE:
- return (n > 0);
- case GLU_TESS_WINDING_NEGATIVE:
- return (n < 0);
- case GLU_TESS_WINDING_ABS_GEQ_TWO:
- return (n >= 2) || (n <= -2);
- }
- /*LINTED*/
- assert( FALSE );
- /*NOTREACHED*/
- return GL_FALSE; /* avoid compiler complaints */
-}
-
-
-static void ComputeWinding( GLUtesselator *tess, ActiveRegion *reg )
-{
- reg->windingNumber = RegionAbove(reg)->windingNumber + reg->eUp->winding;
- reg->inside = IsWindingInside( tess, reg->windingNumber );
-}
-
-
-static void FinishRegion( GLUtesselator *tess, ActiveRegion *reg )
-/*
- * Delete a region from the sweep line. This happens when the upper
- * and lower chains of a region meet (at a vertex on the sweep line).
- * The "inside" flag is copied to the appropriate mesh face (we could
- * not do this before -- since the structure of the mesh is always
- * changing, this face may not have even existed until now).
- */
-{
- GLUhalfEdge *e = reg->eUp;
- GLUface *f = e->Lface;
-
- f->inside = reg->inside;
- f->anEdge = e; /* optimization for __gl_meshTessellateMonoRegion() */
- DeleteRegion( tess, reg );
-}
-
-
-static GLUhalfEdge *FinishLeftRegions( GLUtesselator *tess,
- ActiveRegion *regFirst, ActiveRegion *regLast )
-/*
- * We are given a vertex with one or more left-going edges. All affected
- * edges should be in the edge dictionary. Starting at regFirst->eUp,
- * we walk down deleting all regions where both edges have the same
- * origin vOrg. At the same time we copy the "inside" flag from the
- * active region to the face, since at this point each face will belong
- * to at most one region (this was not necessarily true until this point
- * in the sweep). The walk stops at the region above regLast; if regLast
- * is NULL we walk as far as possible. At the same time we relink the
- * mesh if necessary, so that the ordering of edges around vOrg is the
- * same as in the dictionary.
- */
-{
- ActiveRegion *reg, *regPrev;
- GLUhalfEdge *e, *ePrev;
-
- regPrev = regFirst;
- ePrev = regFirst->eUp;
- while( regPrev != regLast ) {
- regPrev->fixUpperEdge = FALSE; /* placement was OK */
- reg = RegionBelow( regPrev );
- e = reg->eUp;
- if( e->Org != ePrev->Org ) {
- if( ! reg->fixUpperEdge ) {
- /* Remove the last left-going edge. Even though there are no further
- * edges in the dictionary with this origin, there may be further
- * such edges in the mesh (if we are adding left edges to a vertex
- * that has already been processed). Thus it is important to call
- * FinishRegion rather than just DeleteRegion.
- */
- FinishRegion( tess, regPrev );
- break;
- }
- /* If the edge below was a temporary edge introduced by
- * ConnectRightVertex, now is the time to fix it.
- */
- e = __gl_meshConnect( ePrev->Lprev, e->Sym );
- if (e == NULL) longjmp(tess->env,1);
- if ( !FixUpperEdge( reg, e ) ) longjmp(tess->env,1);
- }
-
- /* Relink edges so that ePrev->Onext == e */
- if( ePrev->Onext != e ) {
- if ( !__gl_meshSplice( e->Oprev, e ) ) longjmp(tess->env,1);
- if ( !__gl_meshSplice( ePrev, e ) ) longjmp(tess->env,1);
- }
- FinishRegion( tess, regPrev ); /* may change reg->eUp */
- ePrev = reg->eUp;
- regPrev = reg;
- }
- return ePrev;
-}
-
-
-static void AddRightEdges( GLUtesselator *tess, ActiveRegion *regUp,
- GLUhalfEdge *eFirst, GLUhalfEdge *eLast, GLUhalfEdge *eTopLeft,
- GLboolean cleanUp )
-/*
- * Purpose: insert right-going edges into the edge dictionary, and update
- * winding numbers and mesh connectivity appropriately. All right-going
- * edges share a common origin vOrg. Edges are inserted CCW starting at
- * eFirst; the last edge inserted is eLast->Oprev. If vOrg has any
- * left-going edges already processed, then eTopLeft must be the edge
- * such that an imaginary upward vertical segment from vOrg would be
- * contained between eTopLeft->Oprev and eTopLeft; otherwise eTopLeft
- * should be NULL.
- */
-{
- ActiveRegion *reg, *regPrev;
- GLUhalfEdge *e, *ePrev;
- int firstTime = TRUE;
-
- /* Insert the new right-going edges in the dictionary */
- e = eFirst;
- do {
- assert( VertLeq( e->Org, e->Dst ));
- AddRegionBelow( tess, regUp, e->Sym );
- e = e->Onext;
- } while ( e != eLast );
-
- /* Walk *all* right-going edges from e->Org, in the dictionary order,
- * updating the winding numbers of each region, and re-linking the mesh
- * edges to match the dictionary ordering (if necessary).
- */
- if( eTopLeft == NULL ) {
- eTopLeft = RegionBelow( regUp )->eUp->Rprev;
- }
- regPrev = regUp;
- ePrev = eTopLeft;
- for( ;; ) {
- reg = RegionBelow( regPrev );
- e = reg->eUp->Sym;
- if( e->Org != ePrev->Org ) break;
-
- if( e->Onext != ePrev ) {
- /* Unlink e from its current position, and relink below ePrev */
- if ( !__gl_meshSplice( e->Oprev, e ) ) longjmp(tess->env,1);
- if ( !__gl_meshSplice( ePrev->Oprev, e ) ) longjmp(tess->env,1);
- }
- /* Compute the winding number and "inside" flag for the new regions */
- reg->windingNumber = regPrev->windingNumber - e->winding;
- reg->inside = IsWindingInside( tess, reg->windingNumber );
-
- /* Check for two outgoing edges with same slope -- process these
- * before any intersection tests (see example in __gl_computeInterior).
- */
- regPrev->dirty = TRUE;
- if( ! firstTime && CheckForRightSplice( tess, regPrev )) {
- AddWinding( e, ePrev );
- DeleteRegion( tess, regPrev );
- if ( !__gl_meshDelete( ePrev ) ) longjmp(tess->env,1);
- }
- firstTime = FALSE;
- regPrev = reg;
- ePrev = e;
- }
- regPrev->dirty = TRUE;
- assert( regPrev->windingNumber - e->winding == reg->windingNumber );
-
- if( cleanUp ) {
- /* Check for intersections between newly adjacent edges. */
- WalkDirtyRegions( tess, regPrev );
- }
-}
-
-
-static void CallCombine( GLUtesselator *tess, GLUvertex *isect,
- void *data[4], GLfloat weights[4], int needed )
-{
- GLdouble coords[3];
-
- /* Copy coord data in case the callback changes it. */
- coords[0] = isect->coords[0];
- coords[1] = isect->coords[1];
- coords[2] = isect->coords[2];
-
- isect->data = NULL;
- CALL_COMBINE_OR_COMBINE_DATA( coords, data, weights, &isect->data );
- if( isect->data == NULL ) {
- if( ! needed ) {
- isect->data = data[0];
- } else if( ! tess->fatalError ) {
- /* The only way fatal error is when two edges are found to intersect,
- * but the user has not provided the callback necessary to handle
- * generated intersection points.
- */
- CALL_ERROR_OR_ERROR_DATA( GLU_TESS_NEED_COMBINE_CALLBACK );
- tess->fatalError = TRUE;
- }
- }
-}
-
-static void SpliceMergeVertices( GLUtesselator *tess, GLUhalfEdge *e1,
- GLUhalfEdge *e2 )
-/*
- * Two vertices with idential coordinates are combined into one.
- * e1->Org is kept, while e2->Org is discarded.
- */
-{
- void *data[4] = { NULL, NULL, NULL, NULL };
- GLfloat weights[4] = { 0.5, 0.5, 0.0, 0.0 };
-
- data[0] = e1->Org->data;
- data[1] = e2->Org->data;
- CallCombine( tess, e1->Org, data, weights, FALSE );
- if ( !__gl_meshSplice( e1, e2 ) ) longjmp(tess->env,1);
-}
-
-static void VertexWeights( GLUvertex *isect, GLUvertex *org, GLUvertex *dst,
- GLfloat *weights )
-/*
- * Find some weights which describe how the intersection vertex is
- * a linear combination of "org" and "dest". Each of the two edges
- * which generated "isect" is allocated 50% of the weight; each edge
- * splits the weight between its org and dst according to the
- * relative distance to "isect".
- */
-{
- GLdouble t1 = VertL1dist( org, isect );
- GLdouble t2 = VertL1dist( dst, isect );
-
- weights[0] = 0.5 * t2 / (t1 + t2);
- weights[1] = 0.5 * t1 / (t1 + t2);
- isect->coords[0] += weights[0]*org->coords[0] + weights[1]*dst->coords[0];
- isect->coords[1] += weights[0]*org->coords[1] + weights[1]*dst->coords[1];
- isect->coords[2] += weights[0]*org->coords[2] + weights[1]*dst->coords[2];
-}
-
-
-static void GetIntersectData( GLUtesselator *tess, GLUvertex *isect,
- GLUvertex *orgUp, GLUvertex *dstUp,
- GLUvertex *orgLo, GLUvertex *dstLo )
-/*
- * We've computed a new intersection point, now we need a "data" pointer
- * from the user so that we can refer to this new vertex in the
- * rendering callbacks.
- */
-{
- void *data[4];
- GLfloat weights[4];
-
- data[0] = orgUp->data;
- data[1] = dstUp->data;
- data[2] = orgLo->data;
- data[3] = dstLo->data;
-
- isect->coords[0] = isect->coords[1] = isect->coords[2] = 0;
- VertexWeights( isect, orgUp, dstUp, &weights[0] );
- VertexWeights( isect, orgLo, dstLo, &weights[2] );
-
- CallCombine( tess, isect, data, weights, TRUE );
-}
-
-static int CheckForRightSplice( GLUtesselator *tess, ActiveRegion *regUp )
-/*
- * Check the upper and lower edge of "regUp", to make sure that the
- * eUp->Org is above eLo, or eLo->Org is below eUp (depending on which
- * origin is leftmost).
- *
- * The main purpose is to splice right-going edges with the same
- * dest vertex and nearly identical slopes (ie. we can't distinguish
- * the slopes numerically). However the splicing can also help us
- * to recover from numerical errors. For example, suppose at one
- * point we checked eUp and eLo, and decided that eUp->Org is barely
- * above eLo. Then later, we split eLo into two edges (eg. from
- * a splice operation like this one). This can change the result of
- * our test so that now eUp->Org is incident to eLo, or barely below it.
- * We must correct this condition to maintain the dictionary invariants.
- *
- * One possibility is to check these edges for intersection again
- * (ie. CheckForIntersect). This is what we do if possible. However
- * CheckForIntersect requires that tess->event lies between eUp and eLo,
- * so that it has something to fall back on when the intersection
- * calculation gives us an unusable answer. So, for those cases where
- * we can't check for intersection, this routine fixes the problem
- * by just splicing the offending vertex into the other edge.
- * This is a guaranteed solution, no matter how degenerate things get.
- * Basically this is a combinatorial solution to a numerical problem.
- */
-{
- ActiveRegion *regLo = RegionBelow(regUp);
- GLUhalfEdge *eUp = regUp->eUp;
- GLUhalfEdge *eLo = regLo->eUp;
-
- if( VertLeq( eUp->Org, eLo->Org )) {
- if( EdgeSign( eLo->Dst, eUp->Org, eLo->Org ) > 0 ) return FALSE;
-
- /* eUp->Org appears to be below eLo */
- if( ! VertEq( eUp->Org, eLo->Org )) {
- /* Splice eUp->Org into eLo */
- if ( __gl_meshSplitEdge( eLo->Sym ) == NULL) longjmp(tess->env,1);
- if ( !__gl_meshSplice( eUp, eLo->Oprev ) ) longjmp(tess->env,1);
- regUp->dirty = regLo->dirty = TRUE;
-
- } else if( eUp->Org != eLo->Org ) {
- /* merge the two vertices, discarding eUp->Org */
- pqDelete( tess->pq, eUp->Org->pqHandle ); /* __gl_pqSortDelete */
- SpliceMergeVertices( tess, eLo->Oprev, eUp );
- }
- } else {
- if( EdgeSign( eUp->Dst, eLo->Org, eUp->Org ) < 0 ) return FALSE;
-
- /* eLo->Org appears to be above eUp, so splice eLo->Org into eUp */
- RegionAbove(regUp)->dirty = regUp->dirty = TRUE;
- if (__gl_meshSplitEdge( eUp->Sym ) == NULL) longjmp(tess->env,1);
- if ( !__gl_meshSplice( eLo->Oprev, eUp ) ) longjmp(tess->env,1);
- }
- return TRUE;
-}
-
-static int CheckForLeftSplice( GLUtesselator *tess, ActiveRegion *regUp )
-/*
- * Check the upper and lower edge of "regUp", to make sure that the
- * eUp->Dst is above eLo, or eLo->Dst is below eUp (depending on which
- * destination is rightmost).
- *
- * Theoretically, this should always be true. However, splitting an edge
- * into two pieces can change the results of previous tests. For example,
- * suppose at one point we checked eUp and eLo, and decided that eUp->Dst
- * is barely above eLo. Then later, we split eLo into two edges (eg. from
- * a splice operation like this one). This can change the result of
- * the test so that now eUp->Dst is incident to eLo, or barely below it.
- * We must correct this condition to maintain the dictionary invariants
- * (otherwise new edges might get inserted in the wrong place in the
- * dictionary, and bad stuff will happen).
- *
- * We fix the problem by just splicing the offending vertex into the
- * other edge.
- */
-{
- ActiveRegion *regLo = RegionBelow(regUp);
- GLUhalfEdge *eUp = regUp->eUp;
- GLUhalfEdge *eLo = regLo->eUp;
- GLUhalfEdge *e;
-
- assert( ! VertEq( eUp->Dst, eLo->Dst ));
-
- if( VertLeq( eUp->Dst, eLo->Dst )) {
- if( EdgeSign( eUp->Dst, eLo->Dst, eUp->Org ) < 0 ) return FALSE;
-
- /* eLo->Dst is above eUp, so splice eLo->Dst into eUp */
- RegionAbove(regUp)->dirty = regUp->dirty = TRUE;
- e = __gl_meshSplitEdge( eUp );
- if (e == NULL) longjmp(tess->env,1);
- if ( !__gl_meshSplice( eLo->Sym, e ) ) longjmp(tess->env,1);
- e->Lface->inside = regUp->inside;
- } else {
- if( EdgeSign( eLo->Dst, eUp->Dst, eLo->Org ) > 0 ) return FALSE;
-
- /* eUp->Dst is below eLo, so splice eUp->Dst into eLo */
- regUp->dirty = regLo->dirty = TRUE;
- e = __gl_meshSplitEdge( eLo );
- if (e == NULL) longjmp(tess->env,1);
- if ( !__gl_meshSplice( eUp->Lnext, eLo->Sym ) ) longjmp(tess->env,1);
- e->Rface->inside = regUp->inside;
- }
- return TRUE;
-}
-
-
-static int CheckForIntersect( GLUtesselator *tess, ActiveRegion *regUp )
-/*
- * Check the upper and lower edges of the given region to see if
- * they intersect. If so, create the intersection and add it
- * to the data structures.
- *
- * Returns TRUE if adding the new intersection resulted in a recursive
- * call to AddRightEdges(); in this case all "dirty" regions have been
- * checked for intersections, and possibly regUp has been deleted.
- */
-{
- ActiveRegion *regLo = RegionBelow(regUp);
- GLUhalfEdge *eUp = regUp->eUp;
- GLUhalfEdge *eLo = regLo->eUp;
- GLUvertex *orgUp = eUp->Org;
- GLUvertex *orgLo = eLo->Org;
- GLUvertex *dstUp = eUp->Dst;
- GLUvertex *dstLo = eLo->Dst;
- GLdouble tMinUp, tMaxLo;
- GLUvertex isect, *orgMin;
- GLUhalfEdge *e;
-
- assert( ! VertEq( dstLo, dstUp ));
- assert( EdgeSign( dstUp, tess->event, orgUp ) <= 0 );
- assert( EdgeSign( dstLo, tess->event, orgLo ) >= 0 );
- assert( orgUp != tess->event && orgLo != tess->event );
- assert( ! regUp->fixUpperEdge && ! regLo->fixUpperEdge );
-
- if( orgUp == orgLo ) return FALSE; /* right endpoints are the same */
-
- tMinUp = MIN( orgUp->t, dstUp->t );
- tMaxLo = MAX( orgLo->t, dstLo->t );
- if( tMinUp > tMaxLo ) return FALSE; /* t ranges do not overlap */
-
- if( VertLeq( orgUp, orgLo )) {
- if( EdgeSign( dstLo, orgUp, orgLo ) > 0 ) return FALSE;
- } else {
- if( EdgeSign( dstUp, orgLo, orgUp ) < 0 ) return FALSE;
- }
-
- /* At this point the edges intersect, at least marginally */
- DebugEvent( tess );
-
- __gl_edgeIntersect( dstUp, orgUp, dstLo, orgLo, &isect );
- /* The following properties are guaranteed: */
- assert( MIN( orgUp->t, dstUp->t ) <= isect.t );
- assert( isect.t <= MAX( orgLo->t, dstLo->t ));
- assert( MIN( dstLo->s, dstUp->s ) <= isect.s );
- assert( isect.s <= MAX( orgLo->s, orgUp->s ));
-
- if( VertLeq( &isect, tess->event )) {
- /* The intersection point lies slightly to the left of the sweep line,
- * so move it until it''s slightly to the right of the sweep line.
- * (If we had perfect numerical precision, this would never happen
- * in the first place). The easiest and safest thing to do is
- * replace the intersection by tess->event.
- */
- isect.s = tess->event->s;
- isect.t = tess->event->t;
- }
- /* Similarly, if the computed intersection lies to the right of the
- * rightmost origin (which should rarely happen), it can cause
- * unbelievable inefficiency on sufficiently degenerate inputs.
- * (If you have the test program, try running test54.d with the
- * "X zoom" option turned on).
- */
- orgMin = VertLeq( orgUp, orgLo ) ? orgUp : orgLo;
- if( VertLeq( orgMin, &isect )) {
- isect.s = orgMin->s;
- isect.t = orgMin->t;
- }
-
- if( VertEq( &isect, orgUp ) || VertEq( &isect, orgLo )) {
- /* Easy case -- intersection at one of the right endpoints */
- (void) CheckForRightSplice( tess, regUp );
- return FALSE;
- }
-
- if( (! VertEq( dstUp, tess->event )
- && EdgeSign( dstUp, tess->event, &isect ) >= 0)
- || (! VertEq( dstLo, tess->event )
- && EdgeSign( dstLo, tess->event, &isect ) <= 0 ))
- {
- /* Very unusual -- the new upper or lower edge would pass on the
- * wrong side of the sweep event, or through it. This can happen
- * due to very small numerical errors in the intersection calculation.
- */
- if( dstLo == tess->event ) {
- /* Splice dstLo into eUp, and process the new region(s) */
- if (__gl_meshSplitEdge( eUp->Sym ) == NULL) longjmp(tess->env,1);
- if ( !__gl_meshSplice( eLo->Sym, eUp ) ) longjmp(tess->env,1);
- regUp = TopLeftRegion( regUp );
- if (regUp == NULL) longjmp(tess->env,1);
- eUp = RegionBelow(regUp)->eUp;
- FinishLeftRegions( tess, RegionBelow(regUp), regLo );
- AddRightEdges( tess, regUp, eUp->Oprev, eUp, eUp, TRUE );
- return TRUE;
- }
- if( dstUp == tess->event ) {
- /* Splice dstUp into eLo, and process the new region(s) */
- if (__gl_meshSplitEdge( eLo->Sym ) == NULL) longjmp(tess->env,1);
- if ( !__gl_meshSplice( eUp->Lnext, eLo->Oprev ) ) longjmp(tess->env,1);
- regLo = regUp;
- regUp = TopRightRegion( regUp );
- e = RegionBelow(regUp)->eUp->Rprev;
- regLo->eUp = eLo->Oprev;
- eLo = FinishLeftRegions( tess, regLo, NULL );
- AddRightEdges( tess, regUp, eLo->Onext, eUp->Rprev, e, TRUE );
- return TRUE;
- }
- /* Special case: called from ConnectRightVertex. If either
- * edge passes on the wrong side of tess->event, split it
- * (and wait for ConnectRightVertex to splice it appropriately).
- */
- if( EdgeSign( dstUp, tess->event, &isect ) >= 0 ) {
- RegionAbove(regUp)->dirty = regUp->dirty = TRUE;
- if (__gl_meshSplitEdge( eUp->Sym ) == NULL) longjmp(tess->env,1);
- eUp->Org->s = tess->event->s;
- eUp->Org->t = tess->event->t;
- }
- if( EdgeSign( dstLo, tess->event, &isect ) <= 0 ) {
- regUp->dirty = regLo->dirty = TRUE;
- if (__gl_meshSplitEdge( eLo->Sym ) == NULL) longjmp(tess->env,1);
- eLo->Org->s = tess->event->s;
- eLo->Org->t = tess->event->t;
- }
- /* leave the rest for ConnectRightVertex */
- return FALSE;
- }
-
- /* General case -- split both edges, splice into new vertex.
- * When we do the splice operation, the order of the arguments is
- * arbitrary as far as correctness goes. However, when the operation
- * creates a new face, the work done is proportional to the size of
- * the new face. We expect the faces in the processed part of
- * the mesh (ie. eUp->Lface) to be smaller than the faces in the
- * unprocessed original contours (which will be eLo->Oprev->Lface).
- */
- if (__gl_meshSplitEdge( eUp->Sym ) == NULL) longjmp(tess->env,1);
- if (__gl_meshSplitEdge( eLo->Sym ) == NULL) longjmp(tess->env,1);
- if ( !__gl_meshSplice( eLo->Oprev, eUp ) ) longjmp(tess->env,1);
- eUp->Org->s = isect.s;
- eUp->Org->t = isect.t;
- eUp->Org->pqHandle = pqInsert( tess->pq, eUp->Org ); /* __gl_pqSortInsert */
- if (eUp->Org->pqHandle == LONG_MAX) {
- pqDeletePriorityQ(tess->pq); /* __gl_pqSortDeletePriorityQ */
- tess->pq = NULL;
- longjmp(tess->env,1);
- }
- GetIntersectData( tess, eUp->Org, orgUp, dstUp, orgLo, dstLo );
- RegionAbove(regUp)->dirty = regUp->dirty = regLo->dirty = TRUE;
- return FALSE;
-}
-
-static void WalkDirtyRegions( GLUtesselator *tess, ActiveRegion *regUp )
-/*
- * When the upper or lower edge of any region changes, the region is
- * marked "dirty". This routine walks through all the dirty regions
- * and makes sure that the dictionary invariants are satisfied
- * (see the comments at the beginning of this file). Of course
- * new dirty regions can be created as we make changes to restore
- * the invariants.
- */
-{
- ActiveRegion *regLo = RegionBelow(regUp);
- GLUhalfEdge *eUp, *eLo;
-
- for( ;; ) {
- /* Find the lowest dirty region (we walk from the bottom up). */
- while( regLo->dirty ) {
- regUp = regLo;
- regLo = RegionBelow(regLo);
- }
- if( ! regUp->dirty ) {
- regLo = regUp;
- regUp = RegionAbove( regUp );
- if( regUp == NULL || ! regUp->dirty ) {
- /* We've walked all the dirty regions */
- return;
- }
- }
- regUp->dirty = FALSE;
- eUp = regUp->eUp;
- eLo = regLo->eUp;
-
- if( eUp->Dst != eLo->Dst ) {
- /* Check that the edge ordering is obeyed at the Dst vertices. */
- if( CheckForLeftSplice( tess, regUp )) {
-
- /* If the upper or lower edge was marked fixUpperEdge, then
- * we no longer need it (since these edges are needed only for
- * vertices which otherwise have no right-going edges).
- */
- if( regLo->fixUpperEdge ) {
- DeleteRegion( tess, regLo );
- if ( !__gl_meshDelete( eLo ) ) longjmp(tess->env,1);
- regLo = RegionBelow( regUp );
- eLo = regLo->eUp;
- } else if( regUp->fixUpperEdge ) {
- DeleteRegion( tess, regUp );
- if ( !__gl_meshDelete( eUp ) ) longjmp(tess->env,1);
- regUp = RegionAbove( regLo );
- eUp = regUp->eUp;
- }
- }
- }
- if( eUp->Org != eLo->Org ) {
- if( eUp->Dst != eLo->Dst
- && ! regUp->fixUpperEdge && ! regLo->fixUpperEdge
- && (eUp->Dst == tess->event || eLo->Dst == tess->event) )
- {
- /* When all else fails in CheckForIntersect(), it uses tess->event
- * as the intersection location. To make this possible, it requires
- * that tess->event lie between the upper and lower edges, and also
- * that neither of these is marked fixUpperEdge (since in the worst
- * case it might splice one of these edges into tess->event, and
- * violate the invariant that fixable edges are the only right-going
- * edge from their associated vertex).
- */
- if( CheckForIntersect( tess, regUp )) {
- /* WalkDirtyRegions() was called recursively; we're done */
- return;
- }
- } else {
- /* Even though we can't use CheckForIntersect(), the Org vertices
- * may violate the dictionary edge ordering. Check and correct this.
- */
- (void) CheckForRightSplice( tess, regUp );
- }
- }
- if( eUp->Org == eLo->Org && eUp->Dst == eLo->Dst ) {
- /* A degenerate loop consisting of only two edges -- delete it. */
- AddWinding( eLo, eUp );
- DeleteRegion( tess, regUp );
- if ( !__gl_meshDelete( eUp ) ) longjmp(tess->env,1);
- regUp = RegionAbove( regLo );
- }
- }
-}
-
-
-static void ConnectRightVertex( GLUtesselator *tess, ActiveRegion *regUp,
- GLUhalfEdge *eBottomLeft )
-/*
- * Purpose: connect a "right" vertex vEvent (one where all edges go left)
- * to the unprocessed portion of the mesh. Since there are no right-going
- * edges, two regions (one above vEvent and one below) are being merged
- * into one. "regUp" is the upper of these two regions.
- *
- * There are two reasons for doing this (adding a right-going edge):
- * - if the two regions being merged are "inside", we must add an edge
- * to keep them separated (the combined region would not be monotone).
- * - in any case, we must leave some record of vEvent in the dictionary,
- * so that we can merge vEvent with features that we have not seen yet.
- * For example, maybe there is a vertical edge which passes just to
- * the right of vEvent; we would like to splice vEvent into this edge.
- *
- * However, we don't want to connect vEvent to just any vertex. We don''t
- * want the new edge to cross any other edges; otherwise we will create
- * intersection vertices even when the input data had no self-intersections.
- * (This is a bad thing; if the user's input data has no intersections,
- * we don't want to generate any false intersections ourselves.)
- *
- * Our eventual goal is to connect vEvent to the leftmost unprocessed
- * vertex of the combined region (the union of regUp and regLo).
- * But because of unseen vertices with all right-going edges, and also
- * new vertices which may be created by edge intersections, we don''t
- * know where that leftmost unprocessed vertex is. In the meantime, we
- * connect vEvent to the closest vertex of either chain, and mark the region
- * as "fixUpperEdge". This flag says to delete and reconnect this edge
- * to the next processed vertex on the boundary of the combined region.
- * Quite possibly the vertex we connected to will turn out to be the
- * closest one, in which case we won''t need to make any changes.
- */
-{
- GLUhalfEdge *eNew;
- GLUhalfEdge *eTopLeft = eBottomLeft->Onext;
- ActiveRegion *regLo = RegionBelow(regUp);
- GLUhalfEdge *eUp = regUp->eUp;
- GLUhalfEdge *eLo = regLo->eUp;
- int degenerate = FALSE;
-
- if( eUp->Dst != eLo->Dst ) {
- (void) CheckForIntersect( tess, regUp );
- }
-
- /* Possible new degeneracies: upper or lower edge of regUp may pass
- * through vEvent, or may coincide with new intersection vertex
- */
- if( VertEq( eUp->Org, tess->event )) {
- if ( !__gl_meshSplice( eTopLeft->Oprev, eUp ) ) longjmp(tess->env,1);
- regUp = TopLeftRegion( regUp );
- if (regUp == NULL) longjmp(tess->env,1);
- eTopLeft = RegionBelow( regUp )->eUp;
- FinishLeftRegions( tess, RegionBelow(regUp), regLo );
- degenerate = TRUE;
- }
- if( VertEq( eLo->Org, tess->event )) {
- if ( !__gl_meshSplice( eBottomLeft, eLo->Oprev ) ) longjmp(tess->env,1);
- eBottomLeft = FinishLeftRegions( tess, regLo, NULL );
- degenerate = TRUE;
- }
- if( degenerate ) {
- AddRightEdges( tess, regUp, eBottomLeft->Onext, eTopLeft, eTopLeft, TRUE );
- return;
- }
-
- /* Non-degenerate situation -- need to add a temporary, fixable edge.
- * Connect to the closer of eLo->Org, eUp->Org.
- */
- if( VertLeq( eLo->Org, eUp->Org )) {
- eNew = eLo->Oprev;
- } else {
- eNew = eUp;
- }
- eNew = __gl_meshConnect( eBottomLeft->Lprev, eNew );
- if (eNew == NULL) longjmp(tess->env,1);
-
- /* Prevent cleanup, otherwise eNew might disappear before we've even
- * had a chance to mark it as a temporary edge.
- */
- AddRightEdges( tess, regUp, eNew, eNew->Onext, eNew->Onext, FALSE );
- eNew->Sym->activeRegion->fixUpperEdge = TRUE;
- WalkDirtyRegions( tess, regUp );
-}
-
-/* Because vertices at exactly the same location are merged together
- * before we process the sweep event, some degenerate cases can't occur.
- * However if someone eventually makes the modifications required to
- * merge features which are close together, the cases below marked
- * TOLERANCE_NONZERO will be useful. They were debugged before the
- * code to merge identical vertices in the main loop was added.
- */
-#define TOLERANCE_NONZERO FALSE
-
-static void ConnectLeftDegenerate( GLUtesselator *tess,
- ActiveRegion *regUp, GLUvertex *vEvent )
-/*
- * The event vertex lies exacty on an already-processed edge or vertex.
- * Adding the new vertex involves splicing it into the already-processed
- * part of the mesh.
- */
-{
- GLUhalfEdge *e, *eTopLeft, *eTopRight, *eLast;
- ActiveRegion *reg;
-
- e = regUp->eUp;
- if( VertEq( e->Org, vEvent )) {
- /* e->Org is an unprocessed vertex - just combine them, and wait
- * for e->Org to be pulled from the queue
- */
- assert( TOLERANCE_NONZERO );
- SpliceMergeVertices( tess, e, vEvent->anEdge );
- return;
- }
-
- if( ! VertEq( e->Dst, vEvent )) {
- /* General case -- splice vEvent into edge e which passes through it */
- if (__gl_meshSplitEdge( e->Sym ) == NULL) longjmp(tess->env,1);
- if( regUp->fixUpperEdge ) {
- /* This edge was fixable -- delete unused portion of original edge */
- if ( !__gl_meshDelete( e->Onext ) ) longjmp(tess->env,1);
- regUp->fixUpperEdge = FALSE;
- }
- if ( !__gl_meshSplice( vEvent->anEdge, e ) ) longjmp(tess->env,1);
- SweepEvent( tess, vEvent ); /* recurse */
- return;
- }
-
- /* vEvent coincides with e->Dst, which has already been processed.
- * Splice in the additional right-going edges.
- */
- assert( TOLERANCE_NONZERO );
- regUp = TopRightRegion( regUp );
- reg = RegionBelow( regUp );
- eTopRight = reg->eUp->Sym;
- eTopLeft = eLast = eTopRight->Onext;
- if( reg->fixUpperEdge ) {
- /* Here e->Dst has only a single fixable edge going right.
- * We can delete it since now we have some real right-going edges.
- */
- assert( eTopLeft != eTopRight ); /* there are some left edges too */
- DeleteRegion( tess, reg );
- if ( !__gl_meshDelete( eTopRight ) ) longjmp(tess->env,1);
- eTopRight = eTopLeft->Oprev;
- }
- if ( !__gl_meshSplice( vEvent->anEdge, eTopRight ) ) longjmp(tess->env,1);
- if( ! EdgeGoesLeft( eTopLeft )) {
- /* e->Dst had no left-going edges -- indicate this to AddRightEdges() */
- eTopLeft = NULL;
- }
- AddRightEdges( tess, regUp, eTopRight->Onext, eLast, eTopLeft, TRUE );
-}
-
-
-static void ConnectLeftVertex( GLUtesselator *tess, GLUvertex *vEvent )
-/*
- * Purpose: connect a "left" vertex (one where both edges go right)
- * to the processed portion of the mesh. Let R be the active region
- * containing vEvent, and let U and L be the upper and lower edge
- * chains of R. There are two possibilities:
- *
- * - the normal case: split R into two regions, by connecting vEvent to
- * the rightmost vertex of U or L lying to the left of the sweep line
- *
- * - the degenerate case: if vEvent is close enough to U or L, we
- * merge vEvent into that edge chain. The subcases are:
- * - merging with the rightmost vertex of U or L
- * - merging with the active edge of U or L
- * - merging with an already-processed portion of U or L
- */
-{
- ActiveRegion *regUp, *regLo, *reg;
- GLUhalfEdge *eUp, *eLo, *eNew;
- ActiveRegion tmp;
-
- /* assert( vEvent->anEdge->Onext->Onext == vEvent->anEdge ); */
-
- /* Get a pointer to the active region containing vEvent */
- tmp.eUp = vEvent->anEdge->Sym;
- /* __GL_DICTLISTKEY */ /* __gl_dictListSearch */
- regUp = (ActiveRegion *)dictKey( dictSearch( tess->dict, &tmp ));
- regLo = RegionBelow( regUp );
- eUp = regUp->eUp;
- eLo = regLo->eUp;
-
- /* Try merging with U or L first */
- if( EdgeSign( eUp->Dst, vEvent, eUp->Org ) == 0 ) {
- ConnectLeftDegenerate( tess, regUp, vEvent );
- return;
- }
-
- /* Connect vEvent to rightmost processed vertex of either chain.
- * e->Dst is the vertex that we will connect to vEvent.
- */
- reg = VertLeq( eLo->Dst, eUp->Dst ) ? regUp : regLo;
-
- if( regUp->inside || reg->fixUpperEdge) {
- if( reg == regUp ) {
- eNew = __gl_meshConnect( vEvent->anEdge->Sym, eUp->Lnext );
- if (eNew == NULL) longjmp(tess->env,1);
- } else {
- GLUhalfEdge *tempHalfEdge= __gl_meshConnect( eLo->Dnext, vEvent->anEdge);
- if (tempHalfEdge == NULL) longjmp(tess->env,1);
-
- eNew = tempHalfEdge->Sym;
- }
- if( reg->fixUpperEdge ) {
- if ( !FixUpperEdge( reg, eNew ) ) longjmp(tess->env,1);
- } else {
- ComputeWinding( tess, AddRegionBelow( tess, regUp, eNew ));
- }
- SweepEvent( tess, vEvent );
- } else {
- /* The new vertex is in a region which does not belong to the polygon.
- * We don''t need to connect this vertex to the rest of the mesh.
- */
- AddRightEdges( tess, regUp, vEvent->anEdge, vEvent->anEdge, NULL, TRUE );
- }
-}
-
-
-static void SweepEvent( GLUtesselator *tess, GLUvertex *vEvent )
-/*
- * Does everything necessary when the sweep line crosses a vertex.
- * Updates the mesh and the edge dictionary.
- */
-{
- ActiveRegion *regUp, *reg;
- GLUhalfEdge *e, *eTopLeft, *eBottomLeft;
-
- tess->event = vEvent; /* for access in EdgeLeq() */
- DebugEvent( tess );
-
- /* Check if this vertex is the right endpoint of an edge that is
- * already in the dictionary. In this case we don't need to waste
- * time searching for the location to insert new edges.
- */
- e = vEvent->anEdge;
- while( e->activeRegion == NULL ) {
- e = e->Onext;
- if( e == vEvent->anEdge ) {
- /* All edges go right -- not incident to any processed edges */
- ConnectLeftVertex( tess, vEvent );
- return;
- }
- }
-
- /* Processing consists of two phases: first we "finish" all the
- * active regions where both the upper and lower edges terminate
- * at vEvent (ie. vEvent is closing off these regions).
- * We mark these faces "inside" or "outside" the polygon according
- * to their winding number, and delete the edges from the dictionary.
- * This takes care of all the left-going edges from vEvent.
- */
- regUp = TopLeftRegion( e->activeRegion );
- if (regUp == NULL) longjmp(tess->env,1);
- reg = RegionBelow( regUp );
- eTopLeft = reg->eUp;
- eBottomLeft = FinishLeftRegions( tess, reg, NULL );
-
- /* Next we process all the right-going edges from vEvent. This
- * involves adding the edges to the dictionary, and creating the
- * associated "active regions" which record information about the
- * regions between adjacent dictionary edges.
- */
- if( eBottomLeft->Onext == eTopLeft ) {
- /* No right-going edges -- add a temporary "fixable" edge */
- ConnectRightVertex( tess, regUp, eBottomLeft );
- } else {
- AddRightEdges( tess, regUp, eBottomLeft->Onext, eTopLeft, eTopLeft, TRUE );
- }
-}
-
-
-/* Make the sentinel coordinates big enough that they will never be
- * merged with real input features. (Even with the largest possible
- * input contour and the maximum tolerance of 1.0, no merging will be
- * done with coordinates larger than 3 * GLU_TESS_MAX_COORD).
- */
-#define SENTINEL_COORD (4 * GLU_TESS_MAX_COORD)
-
-static void AddSentinel( GLUtesselator *tess, GLdouble t )
-/*
- * We add two sentinel edges above and below all other edges,
- * to avoid special cases at the top and bottom.
- */
-{
- GLUhalfEdge *e;
- ActiveRegion *reg = (ActiveRegion *)memAlloc( sizeof( ActiveRegion ));
- if (reg == NULL) longjmp(tess->env,1);
-
- e = __gl_meshMakeEdge( tess->mesh );
- if (e == NULL) longjmp(tess->env,1);
-
- e->Org->s = SENTINEL_COORD;
- e->Org->t = t;
- e->Dst->s = -SENTINEL_COORD;
- e->Dst->t = t;
- tess->event = e->Dst; /* initialize it */
-
- reg->eUp = e;
- reg->windingNumber = 0;
- reg->inside = FALSE;
- reg->fixUpperEdge = FALSE;
- reg->sentinel = TRUE;
- reg->dirty = FALSE;
- reg->nodeUp = dictInsert( tess->dict, reg ); /* __gl_dictListInsertBefore */
- if (reg->nodeUp == NULL) longjmp(tess->env,1);
-}
-
-
-static void InitEdgeDict( GLUtesselator *tess )
-/*
- * We maintain an ordering of edge intersections with the sweep line.
- * This order is maintained in a dynamic dictionary.
- */
-{
- /* __gl_dictListNewDict */
- tess->dict = dictNewDict( tess, (int (*)(void *, DictKey, DictKey)) EdgeLeq );
- if (tess->dict == NULL) longjmp(tess->env,1);
-
- AddSentinel( tess, -SENTINEL_COORD );
- AddSentinel( tess, SENTINEL_COORD );
-}
-
-
-static void DoneEdgeDict( GLUtesselator *tess )
-{
- ActiveRegion *reg;
-#ifndef NDEBUG
- int fixedEdges = 0;
-#endif
-
- /* __GL_DICTLISTKEY */ /* __GL_DICTLISTMIN */
- while( (reg = (ActiveRegion *)dictKey( dictMin( tess->dict ))) != NULL ) {
- /*
- * At the end of all processing, the dictionary should contain
- * only the two sentinel edges, plus at most one "fixable" edge
- * created by ConnectRightVertex().
- */
- if( ! reg->sentinel ) {
- assert( reg->fixUpperEdge );
- assert( ++fixedEdges == 1 );
- }
- assert( reg->windingNumber == 0 );
- DeleteRegion( tess, reg );
-/* __gl_meshDelete( reg->eUp );*/
- }
- dictDeleteDict( tess->dict ); /* __gl_dictListDeleteDict */
-}
-
-
-static void RemoveDegenerateEdges( GLUtesselator *tess )
-/*
- * Remove zero-length edges, and contours with fewer than 3 vertices.
- */
-{
- GLUhalfEdge *e, *eNext, *eLnext;
- GLUhalfEdge *eHead = &tess->mesh->eHead;
-
- /*LINTED*/
- for( e = eHead->next; e != eHead; e = eNext ) {
- eNext = e->next;
- eLnext = e->Lnext;
-
- if( VertEq( e->Org, e->Dst ) && e->Lnext->Lnext != e ) {
- /* Zero-length edge, contour has at least 3 edges */
-
- SpliceMergeVertices( tess, eLnext, e ); /* deletes e->Org */
- if ( !__gl_meshDelete( e ) ) longjmp(tess->env,1); /* e is a self-loop */
- e = eLnext;
- eLnext = e->Lnext;
- }
- if( eLnext->Lnext == e ) {
- /* Degenerate contour (one or two edges) */
-
- if( eLnext != e ) {
- if( eLnext == eNext || eLnext == eNext->Sym ) { eNext = eNext->next; }
- if ( !__gl_meshDelete( eLnext ) ) longjmp(tess->env,1);
- }
- if( e == eNext || e == eNext->Sym ) { eNext = eNext->next; }
- if ( !__gl_meshDelete( e ) ) longjmp(tess->env,1);
- }
- }
-}
-
-static int InitPriorityQ( GLUtesselator *tess )
-/*
- * Insert all vertices into the priority queue which determines the
- * order in which vertices cross the sweep line.
- */
-{
- PriorityQ *pq;
- GLUvertex *v, *vHead;
-
- /* __gl_pqSortNewPriorityQ */
- pq = tess->pq = pqNewPriorityQ( (int (*)(PQkey, PQkey)) __gl_vertLeq );
- if (pq == NULL) return 0;
-
- vHead = &tess->mesh->vHead;
- for( v = vHead->next; v != vHead; v = v->next ) {
- v->pqHandle = pqInsert( pq, v ); /* __gl_pqSortInsert */
- if (v->pqHandle == LONG_MAX) break;
- }
- if (v != vHead || !pqInit( pq ) ) { /* __gl_pqSortInit */
- pqDeletePriorityQ(tess->pq); /* __gl_pqSortDeletePriorityQ */
- tess->pq = NULL;
- return 0;
- }
-
- return 1;
-}
-
-
-static void DonePriorityQ( GLUtesselator *tess )
-{
- pqDeletePriorityQ( tess->pq ); /* __gl_pqSortDeletePriorityQ */
-}
-
-
-static int RemoveDegenerateFaces( GLUmesh *mesh )
-/*
- * Delete any degenerate faces with only two edges. WalkDirtyRegions()
- * will catch almost all of these, but it won't catch degenerate faces
- * produced by splice operations on already-processed edges.
- * The two places this can happen are in FinishLeftRegions(), when
- * we splice in a "temporary" edge produced by ConnectRightVertex(),
- * and in CheckForLeftSplice(), where we splice already-processed
- * edges to ensure that our dictionary invariants are not violated
- * by numerical errors.
- *
- * In both these cases it is *very* dangerous to delete the offending
- * edge at the time, since one of the routines further up the stack
- * will sometimes be keeping a pointer to that edge.
- */
-{
- GLUface *f, *fNext;
- GLUhalfEdge *e;
-
- /*LINTED*/
- for( f = mesh->fHead.next; f != &mesh->fHead; f = fNext ) {
- fNext = f->next;
- e = f->anEdge;
- assert( e->Lnext != e );
-
- if( e->Lnext->Lnext == e ) {
- /* A face with only two edges */
- AddWinding( e->Onext, e );
- if ( !__gl_meshDelete( e ) ) return 0;
- }
- }
- return 1;
-}
-
-int __gl_computeInterior( GLUtesselator *tess )
-/*
- * __gl_computeInterior( tess ) computes the planar arrangement specified
- * by the given contours, and further subdivides this arrangement
- * into regions. Each region is marked "inside" if it belongs
- * to the polygon, according to the rule given by tess->windingRule.
- * Each interior region is guaranteed be monotone.
- */
-{
- GLUvertex *v, *vNext;
-
- tess->fatalError = FALSE;
-
- /* Each vertex defines an event for our sweep line. Start by inserting
- * all the vertices in a priority queue. Events are processed in
- * lexicographic order, ie.
- *
- * e1 < e2 iff e1.x < e2.x || (e1.x == e2.x && e1.y < e2.y)
- */
- RemoveDegenerateEdges( tess );
- if ( !InitPriorityQ( tess ) ) return 0; /* if error */
- InitEdgeDict( tess );
-
- /* __gl_pqSortExtractMin */
- while( (v = (GLUvertex *)pqExtractMin( tess->pq )) != NULL ) {
- for( ;; ) {
- vNext = (GLUvertex *)pqMinimum( tess->pq ); /* __gl_pqSortMinimum */
- if( vNext == NULL || ! VertEq( vNext, v )) break;
-
- /* Merge together all vertices at exactly the same location.
- * This is more efficient than processing them one at a time,
- * simplifies the code (see ConnectLeftDegenerate), and is also
- * important for correct handling of certain degenerate cases.
- * For example, suppose there are two identical edges A and B
- * that belong to different contours (so without this code they would
- * be processed by separate sweep events). Suppose another edge C
- * crosses A and B from above. When A is processed, we split it
- * at its intersection point with C. However this also splits C,
- * so when we insert B we may compute a slightly different
- * intersection point. This might leave two edges with a small
- * gap between them. This kind of error is especially obvious
- * when using boundary extraction (GLU_TESS_BOUNDARY_ONLY).
- */
- vNext = (GLUvertex *)pqExtractMin( tess->pq ); /* __gl_pqSortExtractMin*/
- SpliceMergeVertices( tess, v->anEdge, vNext->anEdge );
- }
- SweepEvent( tess, v );
- }
-
- /* Set tess->event for debugging purposes */
- /* __GL_DICTLISTKEY */ /* __GL_DICTLISTMIN */
- tess->event = ((ActiveRegion *) dictKey( dictMin( tess->dict )))->eUp->Org;
- DebugEvent( tess );
- DoneEdgeDict( tess );
- DonePriorityQ( tess );
-
- if ( !RemoveDegenerateFaces( tess->mesh ) ) return 0;
- __gl_meshCheckMesh( tess->mesh );
-
- return 1;
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#ifndef __sweep_h_
-#define __sweep_h_
-
-#include "mesh.h"
-
-/* __gl_computeInterior( tess ) computes the planar arrangement specified
- * by the given contours, and further subdivides this arrangement
- * into regions. Each region is marked "inside" if it belongs
- * to the polygon, according to the rule given by tess->windingRule.
- * Each interior region is guaranteed be monotone.
- */
-int __gl_computeInterior( GLUtesselator *tess );
-
-
-/* The following is here *only* for access by debugging routines */
-
-#include "dict.h"
-
-/* For each pair of adjacent edges crossing the sweep line, there is
- * an ActiveRegion to represent the region between them. The active
- * regions are kept in sorted order in a dynamic dictionary. As the
- * sweep line crosses each vertex, we update the affected regions.
- */
-
-struct ActiveRegion {
- GLUhalfEdge *eUp; /* upper edge, directed right to left */
- DictNode *nodeUp; /* dictionary node corresponding to eUp */
- int windingNumber; /* used to determine which regions are
- * inside the polygon */
- GLboolean inside; /* is this region inside the polygon? */
- GLboolean sentinel; /* marks fake edges at t = +/-infinity */
- GLboolean dirty; /* marks regions where the upper or lower
- * edge has changed, but we haven't checked
- * whether they intersect yet */
- GLboolean fixUpperEdge; /* marks temporary edges introduced when
- * we process a "right vertex" (one without
- * any edges leaving to the right) */
-};
-
-#define RegionBelow(r) ((ActiveRegion *) dictKey(dictPred((r)->nodeUp)))
-#define RegionAbove(r) ((ActiveRegion *) dictKey(dictSucc((r)->nodeUp)))
-
-#endif
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#include "gluos.h"
-#include <stddef.h>
-#include <assert.h>
-#include <setjmp.h>
-#include "memalloc.h"
-#include "tess.h"
-#include "mesh.h"
-#include "normal.h"
-#include "sweep.h"
-#include "tessmono.h"
-#include "render.h"
-
-#define GLU_TESS_DEFAULT_TOLERANCE 0.0
-#define GLU_TESS_MESH 100112 /* void (*)(GLUmesh *mesh) */
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-/*ARGSUSED*/ static void GLAPIENTRY noBegin( GLenum type ) {}
-/*ARGSUSED*/ static void GLAPIENTRY noEdgeFlag( GLboolean boundaryEdge ) {}
-/*ARGSUSED*/ static void GLAPIENTRY noVertex( void *data ) {}
-/*ARGSUSED*/ static void GLAPIENTRY noEnd( void ) {}
-/*ARGSUSED*/ static void GLAPIENTRY noError( GLenum errnum ) {}
-/*ARGSUSED*/ static void GLAPIENTRY noCombine( GLdouble coords[3], void *data[4],
- GLfloat weight[4], void **dataOut ) {}
-/*ARGSUSED*/ static void GLAPIENTRY noMesh( GLUmesh *mesh ) {}
-
-
-/*ARGSUSED*/ void GLAPIENTRY __gl_noBeginData( GLenum type,
- void *polygonData ) {}
-/*ARGSUSED*/ void GLAPIENTRY __gl_noEdgeFlagData( GLboolean boundaryEdge,
- void *polygonData ) {}
-/*ARGSUSED*/ void GLAPIENTRY __gl_noVertexData( void *data,
- void *polygonData ) {}
-/*ARGSUSED*/ void GLAPIENTRY __gl_noEndData( void *polygonData ) {}
-/*ARGSUSED*/ void GLAPIENTRY __gl_noErrorData( GLenum errnum,
- void *polygonData ) {}
-/*ARGSUSED*/ void GLAPIENTRY __gl_noCombineData( GLdouble coords[3],
- void *data[4],
- GLfloat weight[4],
- void **outData,
- void *polygonData ) {}
-
-/* Half-edges are allocated in pairs (see mesh.c) */
-typedef struct { GLUhalfEdge e, eSym; } EdgePair;
-
-#undef MAX
-#define MAX(a,b) ((a) > (b) ? (a) : (b))
-#define MAX_FAST_ALLOC (MAX(sizeof(EdgePair), \
- MAX(sizeof(GLUvertex),sizeof(GLUface))))
-
-
-GLUtesselator * GLAPIENTRY
-gluNewTess( void )
-{
- GLUtesselator *tess;
-
- /* Only initialize fields which can be changed by the api. Other fields
- * are initialized where they are used.
- */
-
- if (memInit( MAX_FAST_ALLOC ) == 0) {
- return 0; /* out of memory */
- }
- tess = (GLUtesselator *)memAlloc( sizeof( GLUtesselator ));
- if (tess == NULL) {
- return 0; /* out of memory */
- }
-
- tess->state = T_DORMANT;
-
- tess->normal[0] = 0;
- tess->normal[1] = 0;
- tess->normal[2] = 0;
-
- tess->relTolerance = GLU_TESS_DEFAULT_TOLERANCE;
- tess->windingRule = GLU_TESS_WINDING_ODD;
- tess->flagBoundary = FALSE;
- tess->boundaryOnly = FALSE;
-
- tess->callBegin = &noBegin;
- tess->callEdgeFlag = &noEdgeFlag;
- tess->callVertex = &noVertex;
- tess->callEnd = &noEnd;
-
- tess->callError = &noError;
- tess->callCombine = &noCombine;
- tess->callMesh = &noMesh;
-
- tess->callBeginData= &__gl_noBeginData;
- tess->callEdgeFlagData= &__gl_noEdgeFlagData;
- tess->callVertexData= &__gl_noVertexData;
- tess->callEndData= &__gl_noEndData;
- tess->callErrorData= &__gl_noErrorData;
- tess->callCombineData= &__gl_noCombineData;
-
- tess->polygonData= NULL;
-
- return tess;
-}
-
-static void MakeDormant( GLUtesselator *tess )
-{
- /* Return the tessellator to its original dormant state. */
-
- if( tess->mesh != NULL ) {
- __gl_meshDeleteMesh( tess->mesh );
- }
- tess->state = T_DORMANT;
- tess->lastEdge = NULL;
- tess->mesh = NULL;
-}
-
-#define RequireState( tess, s ) if( tess->state != s ) GotoState(tess,s)
-
-static void GotoState( GLUtesselator *tess, enum TessState newState )
-{
- while( tess->state != newState ) {
- /* We change the current state one level at a time, to get to
- * the desired state.
- */
- if( tess->state < newState ) {
- switch( tess->state ) {
- case T_DORMANT:
- CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_BEGIN_POLYGON );
- gluTessBeginPolygon( tess, NULL );
- break;
- case T_IN_POLYGON:
- CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_BEGIN_CONTOUR );
- gluTessBeginContour( tess );
- break;
- default:
- ;
- }
- } else {
- switch( tess->state ) {
- case T_IN_CONTOUR:
- CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_END_CONTOUR );
- gluTessEndContour( tess );
- break;
- case T_IN_POLYGON:
- CALL_ERROR_OR_ERROR_DATA( GLU_TESS_MISSING_END_POLYGON );
- /* gluTessEndPolygon( tess ) is too much work! */
- MakeDormant( tess );
- break;
- default:
- ;
- }
- }
- }
-}
-
-
-void GLAPIENTRY
-gluDeleteTess( GLUtesselator *tess )
-{
- RequireState( tess, T_DORMANT );
- memFree( tess );
-}
-
-
-void GLAPIENTRY
-gluTessProperty( GLUtesselator *tess, GLenum which, GLdouble value )
-{
- GLenum windingRule;
-
- switch( which ) {
- case GLU_TESS_TOLERANCE:
- if( value < 0.0 || value > 1.0 ) break;
- tess->relTolerance = value;
- return;
-
- case GLU_TESS_WINDING_RULE:
- windingRule = (GLenum) value;
- if( windingRule != value ) break; /* not an integer */
-
- switch( windingRule ) {
- case GLU_TESS_WINDING_ODD:
- case GLU_TESS_WINDING_NONZERO:
- case GLU_TESS_WINDING_POSITIVE:
- case GLU_TESS_WINDING_NEGATIVE:
- case GLU_TESS_WINDING_ABS_GEQ_TWO:
- tess->windingRule = windingRule;
- return;
- default:
- break;
- }
-
- case GLU_TESS_BOUNDARY_ONLY:
- tess->boundaryOnly = (value != 0);
- return;
-
- default:
- CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_ENUM );
- return;
- }
- CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_VALUE );
-}
-
-/* Returns tessellator property */
-void GLAPIENTRY
-gluGetTessProperty( GLUtesselator *tess, GLenum which, GLdouble *value )
-{
- switch (which) {
- case GLU_TESS_TOLERANCE:
- /* tolerance should be in range [0..1] */
- assert(0.0 <= tess->relTolerance && tess->relTolerance <= 1.0);
- *value= tess->relTolerance;
- break;
- case GLU_TESS_WINDING_RULE:
- assert(tess->windingRule == GLU_TESS_WINDING_ODD ||
- tess->windingRule == GLU_TESS_WINDING_NONZERO ||
- tess->windingRule == GLU_TESS_WINDING_POSITIVE ||
- tess->windingRule == GLU_TESS_WINDING_NEGATIVE ||
- tess->windingRule == GLU_TESS_WINDING_ABS_GEQ_TWO);
- *value= tess->windingRule;
- break;
- case GLU_TESS_BOUNDARY_ONLY:
- assert(tess->boundaryOnly == TRUE || tess->boundaryOnly == FALSE);
- *value= tess->boundaryOnly;
- break;
- default:
- *value= 0.0;
- CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_ENUM );
- break;
- }
-} /* gluGetTessProperty() */
-
-void GLAPIENTRY
-gluTessNormal( GLUtesselator *tess, GLdouble x, GLdouble y, GLdouble z )
-{
- tess->normal[0] = x;
- tess->normal[1] = y;
- tess->normal[2] = z;
-}
-
-void GLAPIENTRY
-gluTessCallback( GLUtesselator *tess, GLenum which, _GLUfuncptr fn)
-{
- switch( which ) {
- case GLU_TESS_BEGIN:
- tess->callBegin = (fn == NULL) ? &noBegin : (void (GLAPIENTRY *)(GLenum)) fn;
- return;
- case GLU_TESS_BEGIN_DATA:
- tess->callBeginData = (fn == NULL) ?
- &__gl_noBeginData : (void (GLAPIENTRY *)(GLenum, void *)) fn;
- return;
- case GLU_TESS_EDGE_FLAG:
- tess->callEdgeFlag = (fn == NULL) ? &noEdgeFlag :
- (void (GLAPIENTRY *)(GLboolean)) fn;
- /* If the client wants boundary edges to be flagged,
- * we render everything as separate triangles (no strips or fans).
- */
- tess->flagBoundary = (fn != NULL);
- return;
- case GLU_TESS_EDGE_FLAG_DATA:
- tess->callEdgeFlagData= (fn == NULL) ?
- &__gl_noEdgeFlagData : (void (GLAPIENTRY *)(GLboolean, void *)) fn;
- /* If the client wants boundary edges to be flagged,
- * we render everything as separate triangles (no strips or fans).
- */
- tess->flagBoundary = (fn != NULL);
- return;
- case GLU_TESS_VERTEX:
- tess->callVertex = (fn == NULL) ? &noVertex :
- (void (GLAPIENTRY *)(void *)) fn;
- return;
- case GLU_TESS_VERTEX_DATA:
- tess->callVertexData = (fn == NULL) ?
- &__gl_noVertexData : (void (GLAPIENTRY *)(void *, void *)) fn;
- return;
- case GLU_TESS_END:
- tess->callEnd = (fn == NULL) ? &noEnd : (void (GLAPIENTRY *)(void)) fn;
- return;
- case GLU_TESS_END_DATA:
- tess->callEndData = (fn == NULL) ? &__gl_noEndData :
- (void (GLAPIENTRY *)(void *)) fn;
- return;
- case GLU_TESS_ERROR:
- tess->callError = (fn == NULL) ? &noError : (void (GLAPIENTRY *)(GLenum)) fn;
- return;
- case GLU_TESS_ERROR_DATA:
- tess->callErrorData = (fn == NULL) ?
- &__gl_noErrorData : (void (GLAPIENTRY *)(GLenum, void *)) fn;
- return;
- case GLU_TESS_COMBINE:
- tess->callCombine = (fn == NULL) ? &noCombine :
- (void (GLAPIENTRY *)(GLdouble [3],void *[4], GLfloat [4], void ** )) fn;
- return;
- case GLU_TESS_COMBINE_DATA:
- tess->callCombineData = (fn == NULL) ? &__gl_noCombineData :
- (void (GLAPIENTRY *)(GLdouble [3],
- void *[4],
- GLfloat [4],
- void **,
- void *)) fn;
- return;
- case GLU_TESS_MESH:
- tess->callMesh = (fn == NULL) ? &noMesh : (void (GLAPIENTRY *)(GLUmesh *)) fn;
- return;
- default:
- CALL_ERROR_OR_ERROR_DATA( GLU_INVALID_ENUM );
- return;
- }
-}
-
-static int AddVertex( GLUtesselator *tess, GLdouble coords[3], void *data )
-{
- GLUhalfEdge *e;
-
- e = tess->lastEdge;
- if( e == NULL ) {
- /* Make a self-loop (one vertex, one edge). */
-
- e = __gl_meshMakeEdge( tess->mesh );
- if (e == NULL) return 0;
- if ( !__gl_meshSplice( e, e->Sym ) ) return 0;
- } else {
- /* Create a new vertex and edge which immediately follow e
- * in the ordering around the left face.
- */
- if (__gl_meshSplitEdge( e ) == NULL) return 0;
- e = e->Lnext;
- }
-
- /* The new vertex is now e->Org. */
- e->Org->data = data;
- e->Org->coords[0] = coords[0];
- e->Org->coords[1] = coords[1];
- e->Org->coords[2] = coords[2];
-
- /* The winding of an edge says how the winding number changes as we
- * cross from the edge''s right face to its left face. We add the
- * vertices in such an order that a CCW contour will add +1 to
- * the winding number of the region inside the contour.
- */
- e->winding = 1;
- e->Sym->winding = -1;
-
- tess->lastEdge = e;
-
- return 1;
-}
-
-
-static void CacheVertex( GLUtesselator *tess, GLdouble coords[3], void *data )
-{
- CachedVertex *v = &tess->cache[tess->cacheCount];
-
- v->data = data;
- v->coords[0] = coords[0];
- v->coords[1] = coords[1];
- v->coords[2] = coords[2];
- ++tess->cacheCount;
-}
-
-
-static int EmptyCache( GLUtesselator *tess )
-{
- CachedVertex *v = tess->cache;
- CachedVertex *vLast;
-
- tess->mesh = __gl_meshNewMesh();
- if (tess->mesh == NULL) return 0;
-
- for( vLast = v + tess->cacheCount; v < vLast; ++v ) {
- if ( !AddVertex( tess, v->coords, v->data ) ) return 0;
- }
- tess->cacheCount = 0;
- tess->emptyCache = FALSE;
-
- return 1;
-}
-
-
-void GLAPIENTRY
-gluTessVertex( GLUtesselator *tess, GLdouble coords[3], void *data )
-{
- int i, tooLarge = FALSE;
- GLdouble x, clamped[3];
-
- RequireState( tess, T_IN_CONTOUR );
-
- if( tess->emptyCache ) {
- if ( !EmptyCache( tess ) ) {
- CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY );
- return;
- }
- tess->lastEdge = NULL;
- }
- for( i = 0; i < 3; ++i ) {
- x = coords[i];
- if( x < - GLU_TESS_MAX_COORD ) {
- x = - GLU_TESS_MAX_COORD;
- tooLarge = TRUE;
- }
- if( x > GLU_TESS_MAX_COORD ) {
- x = GLU_TESS_MAX_COORD;
- tooLarge = TRUE;
- }
- clamped[i] = x;
- }
- if( tooLarge ) {
- CALL_ERROR_OR_ERROR_DATA( GLU_TESS_COORD_TOO_LARGE );
- }
-
- if( tess->mesh == NULL ) {
- if( tess->cacheCount < TESS_MAX_CACHE ) {
- CacheVertex( tess, clamped, data );
- return;
- }
- if ( !EmptyCache( tess ) ) {
- CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY );
- return;
- }
- }
- if ( !AddVertex( tess, clamped, data ) ) {
- CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY );
- }
-}
-
-
-void GLAPIENTRY
-gluTessBeginPolygon( GLUtesselator *tess, void *data )
-{
- RequireState( tess, T_DORMANT );
-
- tess->state = T_IN_POLYGON;
- tess->cacheCount = 0;
- tess->emptyCache = FALSE;
- tess->mesh = NULL;
-
- tess->polygonData= data;
-}
-
-
-void GLAPIENTRY
-gluTessBeginContour( GLUtesselator *tess )
-{
- RequireState( tess, T_IN_POLYGON );
-
- tess->state = T_IN_CONTOUR;
- tess->lastEdge = NULL;
- if( tess->cacheCount > 0 ) {
- /* Just set a flag so we don't get confused by empty contours
- * -- these can be generated accidentally with the obsolete
- * NextContour() interface.
- */
- tess->emptyCache = TRUE;
- }
-}
-
-
-void GLAPIENTRY
-gluTessEndContour( GLUtesselator *tess )
-{
- RequireState( tess, T_IN_CONTOUR );
- tess->state = T_IN_POLYGON;
-}
-
-void GLAPIENTRY
-gluTessEndPolygon( GLUtesselator *tess )
-{
- GLUmesh *mesh;
-
- if (setjmp(tess->env) != 0) {
- /* come back here if out of memory */
- CALL_ERROR_OR_ERROR_DATA( GLU_OUT_OF_MEMORY );
- return;
- }
-
- RequireState( tess, T_IN_POLYGON );
- tess->state = T_DORMANT;
-
- if( tess->mesh == NULL ) {
- if( ! tess->flagBoundary && tess->callMesh == &noMesh ) {
-
- /* Try some special code to make the easy cases go quickly
- * (eg. convex polygons). This code does NOT handle multiple contours,
- * intersections, edge flags, and of course it does not generate
- * an explicit mesh either.
- */
- if( __gl_renderCache( tess )) {
- tess->polygonData= NULL;
- return;
- }
- }
- if ( !EmptyCache( tess ) ) longjmp(tess->env,1); /* could've used a label*/
- }
-
- /* Determine the polygon normal and project vertices onto the plane
- * of the polygon.
- */
- __gl_projectPolygon( tess );
-
- /* __gl_computeInterior( tess ) computes the planar arrangement specified
- * by the given contours, and further subdivides this arrangement
- * into regions. Each region is marked "inside" if it belongs
- * to the polygon, according to the rule given by tess->windingRule.
- * Each interior region is guaranteed be monotone.
- */
- if ( !__gl_computeInterior( tess ) ) {
- longjmp(tess->env,1); /* could've used a label */
- }
-
- mesh = tess->mesh;
- if( ! tess->fatalError ) {
- int rc = 1;
-
- /* If the user wants only the boundary contours, we throw away all edges
- * except those which separate the interior from the exterior.
- * Otherwise we tessellate all the regions marked "inside".
- */
- if( tess->boundaryOnly ) {
- rc = __gl_meshSetWindingNumber( mesh, 1, TRUE );
- } else {
- rc = __gl_meshTessellateInterior( mesh );
- }
- if (rc == 0) longjmp(tess->env,1); /* could've used a label */
-
- __gl_meshCheckMesh( mesh );
-
- if( tess->callBegin != &noBegin || tess->callEnd != &noEnd
- || tess->callVertex != &noVertex || tess->callEdgeFlag != &noEdgeFlag
- || tess->callBeginData != &__gl_noBeginData
- || tess->callEndData != &__gl_noEndData
- || tess->callVertexData != &__gl_noVertexData
- || tess->callEdgeFlagData != &__gl_noEdgeFlagData )
- {
- if( tess->boundaryOnly ) {
- __gl_renderBoundary( tess, mesh ); /* output boundary contours */
- } else {
- __gl_renderMesh( tess, mesh ); /* output strips and fans */
- }
- }
- if( tess->callMesh != &noMesh ) {
-
- /* Throw away the exterior faces, so that all faces are interior.
- * This way the user doesn't have to check the "inside" flag,
- * and we don't need to even reveal its existence. It also leaves
- * the freedom for an implementation to not generate the exterior
- * faces in the first place.
- */
- __gl_meshDiscardExterior( mesh );
- (*tess->callMesh)( mesh ); /* user wants the mesh itself */
- tess->mesh = NULL;
- tess->polygonData= NULL;
- return;
- }
- }
- __gl_meshDeleteMesh( mesh );
- tess->polygonData= NULL;
- tess->mesh = NULL;
-}
-
-
-/*XXXblythe unused function*/
-#if 0
-void GLAPIENTRY
-gluDeleteMesh( GLUmesh *mesh )
-{
- __gl_meshDeleteMesh( mesh );
-}
-#endif
-
-
-
-/*******************************************************/
-
-/* Obsolete calls -- for backward compatibility */
-
-void GLAPIENTRY
-gluBeginPolygon( GLUtesselator *tess )
-{
- gluTessBeginPolygon( tess, NULL );
- gluTessBeginContour( tess );
-}
-
-
-/*ARGSUSED*/
-void GLAPIENTRY
-gluNextContour( GLUtesselator *tess, GLenum type )
-{
- gluTessEndContour( tess );
- gluTessBeginContour( tess );
-}
-
-
-void GLAPIENTRY
-gluEndPolygon( GLUtesselator *tess )
-{
- gluTessEndContour( tess );
- gluTessEndPolygon( tess );
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#ifndef __tess_h_
-#define __tess_h_
-
-#include <GL/glu.h>
-#include <setjmp.h>
-#include "mesh.h"
-#include "dict.h"
-#include "priorityq.h"
-
-/* The begin/end calls must be properly nested. We keep track of
- * the current state to enforce the ordering.
- */
-enum TessState { T_DORMANT, T_IN_POLYGON, T_IN_CONTOUR };
-
-/* We cache vertex data for single-contour polygons so that we can
- * try a quick-and-dirty decomposition first.
- */
-#define TESS_MAX_CACHE 100
-
-typedef struct CachedVertex {
- GLdouble coords[3];
- void *data;
-} CachedVertex;
-
-struct GLUtesselator {
-
- /*** state needed for collecting the input data ***/
-
- enum TessState state; /* what begin/end calls have we seen? */
-
- GLUhalfEdge *lastEdge; /* lastEdge->Org is the most recent vertex */
- GLUmesh *mesh; /* stores the input contours, and eventually
- the tessellation itself */
-
- void (GLAPIENTRY *callError)( GLenum errnum );
-
- /*** state needed for projecting onto the sweep plane ***/
-
- GLdouble normal[3]; /* user-specified normal (if provided) */
- GLdouble sUnit[3]; /* unit vector in s-direction (debugging) */
- GLdouble tUnit[3]; /* unit vector in t-direction (debugging) */
-
- /*** state needed for the line sweep ***/
-
- GLdouble relTolerance; /* tolerance for merging features */
- GLenum windingRule; /* rule for determining polygon interior */
- GLboolean fatalError; /* fatal error: needed combine callback */
-
- Dict *dict; /* edge dictionary for sweep line */
- PriorityQ *pq; /* priority queue of vertex events */
- GLUvertex *event; /* current sweep event being processed */
-
- void (GLAPIENTRY *callCombine)( GLdouble coords[3], void *data[4],
- GLfloat weight[4], void **outData );
-
- /*** state needed for rendering callbacks (see render.c) ***/
-
- GLboolean flagBoundary; /* mark boundary edges (use EdgeFlag) */
- GLboolean boundaryOnly; /* Extract contours, not triangles */
- GLUface *lonelyTriList;
- /* list of triangles which could not be rendered as strips or fans */
-
- void (GLAPIENTRY *callBegin)( GLenum type );
- void (GLAPIENTRY *callEdgeFlag)( GLboolean boundaryEdge );
- void (GLAPIENTRY *callVertex)( void *data );
- void (GLAPIENTRY *callEnd)( void );
- void (GLAPIENTRY *callMesh)( GLUmesh *mesh );
-
-
- /*** state needed to cache single-contour polygons for renderCache() */
-
- GLboolean emptyCache; /* empty cache on next vertex() call */
- int cacheCount; /* number of cached vertices */
- CachedVertex cache[TESS_MAX_CACHE]; /* the vertex data */
-
- /*** rendering callbacks that also pass polygon data ***/
- void (GLAPIENTRY *callBeginData)( GLenum type, void *polygonData );
- void (GLAPIENTRY *callEdgeFlagData)( GLboolean boundaryEdge,
- void *polygonData );
- void (GLAPIENTRY *callVertexData)( void *data, void *polygonData );
- void (GLAPIENTRY *callEndData)( void *polygonData );
- void (GLAPIENTRY *callErrorData)( GLenum errnum, void *polygonData );
- void (GLAPIENTRY *callCombineData)( GLdouble coords[3], void *data[4],
- GLfloat weight[4], void **outData,
- void *polygonData );
-
- jmp_buf env; /* place to jump to when memAllocs fail */
-
- void *polygonData; /* client data for current polygon */
-};
-
-void GLAPIENTRY __gl_noBeginData( GLenum type, void *polygonData );
-void GLAPIENTRY __gl_noEdgeFlagData( GLboolean boundaryEdge, void *polygonData );
-void GLAPIENTRY __gl_noVertexData( void *data, void *polygonData );
-void GLAPIENTRY __gl_noEndData( void *polygonData );
-void GLAPIENTRY __gl_noErrorData( GLenum errnum, void *polygonData );
-void GLAPIENTRY __gl_noCombineData( GLdouble coords[3], void *data[4],
- GLfloat weight[4], void **outData,
- void *polygonData );
-
-#define CALL_BEGIN_OR_BEGIN_DATA(a) \
- if (tess->callBeginData != &__gl_noBeginData) \
- (*tess->callBeginData)((a),tess->polygonData); \
- else (*tess->callBegin)((a));
-
-#define CALL_VERTEX_OR_VERTEX_DATA(a) \
- if (tess->callVertexData != &__gl_noVertexData) \
- (*tess->callVertexData)((a),tess->polygonData); \
- else (*tess->callVertex)((a));
-
-#define CALL_EDGE_FLAG_OR_EDGE_FLAG_DATA(a) \
- if (tess->callEdgeFlagData != &__gl_noEdgeFlagData) \
- (*tess->callEdgeFlagData)((a),tess->polygonData); \
- else (*tess->callEdgeFlag)((a));
-
-#define CALL_END_OR_END_DATA() \
- if (tess->callEndData != &__gl_noEndData) \
- (*tess->callEndData)(tess->polygonData); \
- else (*tess->callEnd)();
-
-#define CALL_COMBINE_OR_COMBINE_DATA(a,b,c,d) \
- if (tess->callCombineData != &__gl_noCombineData) \
- (*tess->callCombineData)((a),(b),(c),(d),tess->polygonData); \
- else (*tess->callCombine)((a),(b),(c),(d));
-
-#define CALL_ERROR_OR_ERROR_DATA(a) \
- if (tess->callErrorData != &__gl_noErrorData) \
- (*tess->callErrorData)((a),tess->polygonData); \
- else (*tess->callError)((a));
-
-#endif
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#include "gluos.h"
-#include <stdlib.h>
-#include "geom.h"
-#include "mesh.h"
-#include "tessmono.h"
-#include <assert.h>
-
-#define AddWinding(eDst,eSrc) (eDst->winding += eSrc->winding, \
- eDst->Sym->winding += eSrc->Sym->winding)
-
-/* __gl_meshTessellateMonoRegion( face ) tessellates a monotone region
- * (what else would it do??) The region must consist of a single
- * loop of half-edges (see mesh.h) oriented CCW. "Monotone" in this
- * case means that any vertical line intersects the interior of the
- * region in a single interval.
- *
- * Tessellation consists of adding interior edges (actually pairs of
- * half-edges), to split the region into non-overlapping triangles.
- *
- * The basic idea is explained in Preparata and Shamos (which I don''t
- * have handy right now), although their implementation is more
- * complicated than this one. The are two edge chains, an upper chain
- * and a lower chain. We process all vertices from both chains in order,
- * from right to left.
- *
- * The algorithm ensures that the following invariant holds after each
- * vertex is processed: the untessellated region consists of two
- * chains, where one chain (say the upper) is a single edge, and
- * the other chain is concave. The left vertex of the single edge
- * is always to the left of all vertices in the concave chain.
- *
- * Each step consists of adding the rightmost unprocessed vertex to one
- * of the two chains, and forming a fan of triangles from the rightmost
- * of two chain endpoints. Determining whether we can add each triangle
- * to the fan is a simple orientation test. By making the fan as large
- * as possible, we restore the invariant (check it yourself).
- */
-int __gl_meshTessellateMonoRegion( GLUface *face )
-{
- GLUhalfEdge *up, *lo;
-
- /* All edges are oriented CCW around the boundary of the region.
- * First, find the half-edge whose origin vertex is rightmost.
- * Since the sweep goes from left to right, face->anEdge should
- * be close to the edge we want.
- */
- up = face->anEdge;
- assert( up->Lnext != up && up->Lnext->Lnext != up );
-
- for( ; VertLeq( up->Dst, up->Org ); up = up->Lprev )
- ;
- for( ; VertLeq( up->Org, up->Dst ); up = up->Lnext )
- ;
- lo = up->Lprev;
-
- while( up->Lnext != lo ) {
- if( VertLeq( up->Dst, lo->Org )) {
- /* up->Dst is on the left. It is safe to form triangles from lo->Org.
- * The EdgeGoesLeft test guarantees progress even when some triangles
- * are CW, given that the upper and lower chains are truly monotone.
- */
- while( lo->Lnext != up && (EdgeGoesLeft( lo->Lnext )
- || EdgeSign( lo->Org, lo->Dst, lo->Lnext->Dst ) <= 0 )) {
- GLUhalfEdge *tempHalfEdge= __gl_meshConnect( lo->Lnext, lo );
- if (tempHalfEdge == NULL) return 0;
- lo = tempHalfEdge->Sym;
- }
- lo = lo->Lprev;
- } else {
- /* lo->Org is on the left. We can make CCW triangles from up->Dst. */
- while( lo->Lnext != up && (EdgeGoesRight( up->Lprev )
- || EdgeSign( up->Dst, up->Org, up->Lprev->Org ) >= 0 )) {
- GLUhalfEdge *tempHalfEdge= __gl_meshConnect( up, up->Lprev );
- if (tempHalfEdge == NULL) return 0;
- up = tempHalfEdge->Sym;
- }
- up = up->Lnext;
- }
- }
-
- /* Now lo->Org == up->Dst == the leftmost vertex. The remaining region
- * can be tessellated in a fan from this leftmost vertex.
- */
- assert( lo->Lnext != up );
- while( lo->Lnext->Lnext != up ) {
- GLUhalfEdge *tempHalfEdge= __gl_meshConnect( lo->Lnext, lo );
- if (tempHalfEdge == NULL) return 0;
- lo = tempHalfEdge->Sym;
- }
-
- return 1;
-}
-
-
-/* __gl_meshTessellateInterior( mesh ) tessellates each region of
- * the mesh which is marked "inside" the polygon. Each such region
- * must be monotone.
- */
-int __gl_meshTessellateInterior( GLUmesh *mesh )
-{
- GLUface *f, *next;
-
- /*LINTED*/
- for( f = mesh->fHead.next; f != &mesh->fHead; f = next ) {
- /* Make sure we don''t try to tessellate the new triangles. */
- next = f->next;
- if( f->inside ) {
- if ( !__gl_meshTessellateMonoRegion( f ) ) return 0;
- }
- }
-
- return 1;
-}
-
-
-/* __gl_meshDiscardExterior( mesh ) zaps (ie. sets to NULL) all faces
- * which are not marked "inside" the polygon. Since further mesh operations
- * on NULL faces are not allowed, the main purpose is to clean up the
- * mesh so that exterior loops are not represented in the data structure.
- */
-void __gl_meshDiscardExterior( GLUmesh *mesh )
-{
- GLUface *f, *next;
-
- /*LINTED*/
- for( f = mesh->fHead.next; f != &mesh->fHead; f = next ) {
- /* Since f will be destroyed, save its next pointer. */
- next = f->next;
- if( ! f->inside ) {
- __gl_meshZapFace( f );
- }
- }
-}
-
-#define MARKED_FOR_DELETION 0x7fffffff
-
-/* __gl_meshSetWindingNumber( mesh, value, keepOnlyBoundary ) resets the
- * winding numbers on all edges so that regions marked "inside" the
- * polygon have a winding number of "value", and regions outside
- * have a winding number of 0.
- *
- * If keepOnlyBoundary is TRUE, it also deletes all edges which do not
- * separate an interior region from an exterior one.
- */
-int __gl_meshSetWindingNumber( GLUmesh *mesh, int value,
- GLboolean keepOnlyBoundary )
-{
- GLUhalfEdge *e, *eNext;
-
- for( e = mesh->eHead.next; e != &mesh->eHead; e = eNext ) {
- eNext = e->next;
- if( e->Rface->inside != e->Lface->inside ) {
-
- /* This is a boundary edge (one side is interior, one is exterior). */
- e->winding = (e->Lface->inside) ? value : -value;
- } else {
-
- /* Both regions are interior, or both are exterior. */
- if( ! keepOnlyBoundary ) {
- e->winding = 0;
- } else {
- if ( !__gl_meshDelete( e ) ) return 0;
- }
- }
- }
- return 1;
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-/*
-** Author: Eric Veach, July 1994.
-**
-*/
-
-#ifndef __tessmono_h_
-#define __tessmono_h_
-
-/* __gl_meshTessellateMonoRegion( face ) tessellates a monotone region
- * (what else would it do??) The region must consist of a single
- * loop of half-edges (see mesh.h) oriented CCW. "Monotone" in this
- * case means that any vertical line intersects the interior of the
- * region in a single interval.
- *
- * Tessellation consists of adding interior edges (actually pairs of
- * half-edges), to split the region into non-overlapping triangles.
- *
- * __gl_meshTessellateInterior( mesh ) tessellates each region of
- * the mesh which is marked "inside" the polygon. Each such region
- * must be monotone.
- *
- * __gl_meshDiscardExterior( mesh ) zaps (ie. sets to NULL) all faces
- * which are not marked "inside" the polygon. Since further mesh operations
- * on NULL faces are not allowed, the main purpose is to clean up the
- * mesh so that exterior loops are not represented in the data structure.
- *
- * __gl_meshSetWindingNumber( mesh, value, keepOnlyBoundary ) resets the
- * winding numbers on all edges so that regions marked "inside" the
- * polygon have a winding number of "value", and regions outside
- * have a winding number of 0.
- *
- * If keepOnlyBoundary is TRUE, it also deletes all edges which do not
- * separate an interior region from an exterior one.
- */
-
-int __gl_meshTessellateMonoRegion( GLUface *face );
-int __gl_meshTessellateInterior( GLUmesh *mesh );
-void __gl_meshDiscardExterior( GLUmesh *mesh );
-int __gl_meshSetWindingNumber( GLUmesh *mesh, int value,
- GLboolean keepOnlyBoundary );
-
-#endif
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#include "gluos.h"
-#include "gluint.h"
-#include <GL/glu.h>
-
-
-struct token_string
-{
- GLuint Token;
- const char *String;
-};
-
-static const struct token_string Errors[] = {
- { GL_NO_ERROR, "no error" },
- { GL_INVALID_ENUM, "invalid enumerant" },
- { GL_INVALID_VALUE, "invalid value" },
- { GL_INVALID_OPERATION, "invalid operation" },
- { GL_STACK_OVERFLOW, "stack overflow" },
- { GL_STACK_UNDERFLOW, "stack underflow" },
- { GL_OUT_OF_MEMORY, "out of memory" },
- { GL_TABLE_TOO_LARGE, "table too large" },
-#ifdef GL_EXT_framebuffer_object
- { GL_INVALID_FRAMEBUFFER_OPERATION_EXT, "invalid framebuffer operation" },
-#endif
- /* GLU */
- { GLU_INVALID_ENUM, "invalid enumerant" },
- { GLU_INVALID_VALUE, "invalid value" },
- { GLU_OUT_OF_MEMORY, "out of memory" },
- { GLU_INCOMPATIBLE_GL_VERSION, "incompatible gl version" },
- { GLU_INVALID_OPERATION, "invalid operation" },
- { ~0, NULL } /* end of list indicator */
-};
-
-
-
-const GLubyte* GLAPIENTRY
-gluErrorString(GLenum errorCode)
-{
- int i;
- for (i = 0; Errors[i].String; i++) {
- if (Errors[i].Token == errorCode)
- return (const GLubyte *) Errors[i].String;
- }
- if ((errorCode >= GLU_NURBS_ERROR1) && (errorCode <= GLU_NURBS_ERROR37)) {
- return (const GLubyte *) __gluNURBSErrorString(errorCode - (GLU_NURBS_ERROR1 - 1));
- }
- if ((errorCode >= GLU_TESS_ERROR1) && (errorCode <= GLU_TESS_ERROR6)) {
- return (const GLubyte *) __gluTessErrorString(errorCode - (GLU_TESS_ERROR1 - 1));
- }
- return (const GLubyte *) 0;
-}
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#include <stdlib.h>
-#include "gluint.h"
-
-static unsigned char *__gluNurbsErrors[] = {
- (unsigned char*) " ",
- (unsigned char*) "spline order un-supported",
- (unsigned char*) "too few knots",
- (unsigned char*) "valid knot range is empty",
- (unsigned char*) "decreasing knot sequence knot",
- (unsigned char*) "knot multiplicity greater than order of spline",
- (unsigned char*) "gluEndCurve() must follow gluBeginCurve()",
- (unsigned char*) "gluBeginCurve() must precede gluEndCurve()",
- (unsigned char*) "missing or extra geometric data",
- (unsigned char*) "can't draw piecewise linear trimming curves",
- (unsigned char*) "missing or extra domain data",
- (unsigned char*) "missing or extra domain data",
- (unsigned char*) "gluEndTrim() must precede gluEndSurface()",
- (unsigned char*) "gluBeginSurface() must precede gluEndSurface()",
- (unsigned char*) "curve of improper type passed as trim curve",
- (unsigned char*) "gluBeginSurface() must precede gluBeginTrim()",
- (unsigned char*) "gluEndTrim() must follow gluBeginTrim()",
- (unsigned char*) "gluBeginTrim() must precede gluEndTrim()",
- (unsigned char*) "invalid or missing trim curve",
- (unsigned char*) "gluBeginTrim() must precede gluPwlCurve()",
- (unsigned char*) "piecewise linear trimming curve referenced twice",
- (unsigned char*) "piecewise linear trimming curve and nurbs curve mixed",
- (unsigned char*) "improper usage of trim data type",
- (unsigned char*) "nurbs curve referenced twice",
- (unsigned char*) "nurbs curve and piecewise linear trimming curve mixed",
- (unsigned char*) "nurbs surface referenced twice",
- (unsigned char*) "invalid property",
- (unsigned char*) "gluEndSurface() must follow gluBeginSurface()",
- (unsigned char*) "intersecting or misoriented trim curves",
- (unsigned char*) "intersecting trim curves",
- (unsigned char*) "UNUSED",
- (unsigned char*) "unconnected trim curves",
- (unsigned char*) "unknown knot error",
- (unsigned char*) "negative vertex count encountered",
- (unsigned char*) "negative byte-stride encounteed",
- (unsigned char*) "unknown type descriptor",
- (unsigned char*) "null control point reference",
- (unsigned char*) "duplicate point on piecewise linear trimming curve",
-};
-
-const unsigned char *__gluNURBSErrorString( int errnum )
-{
- return __gluNurbsErrors[errnum];
-}
-
-static unsigned char *__gluTessErrors[] = {
- (unsigned char*) " ",
- (unsigned char*) "gluTessBeginPolygon() must precede a gluTessEndPolygon()",
- (unsigned char*) "gluTessBeginContour() must precede a gluTessEndContour()",
- (unsigned char*) "gluTessEndPolygon() must follow a gluTessBeginPolygon()",
- (unsigned char*) "gluTessEndContour() must follow a gluTessBeginContour()",
- (unsigned char*) "a coordinate is too large",
- (unsigned char*) "need combine callback",
-};
-
-const unsigned char *__gluTessErrorString( int errnum )
-{
- return __gluTessErrors[errnum];
-} /* __glTessErrorString() */
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#ifndef __gluint_h__
-#define __gluint_h__
-
-extern const unsigned char *__gluNURBSErrorString( int errnum );
-
-extern const unsigned char *__gluTessErrorString( int errnum );
-
-#ifdef _EXTENSIONS_
-#define COS cosf
-#define SIN sinf
-#define SQRT sqrtf
-#else
-#define COS cos
-#define SIN sin
-#define SQRT sqrt
-#endif
-
-#endif /* __gluint_h__ */
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#include "gluos.h"
-#include <assert.h>
-#include <GL/glu.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h> /* UINT_MAX */
-#include <math.h>
-
-typedef union {
- unsigned char ub[4];
- unsigned short us[2];
- unsigned int ui;
- char b[4];
- short s[2];
- int i;
- float f;
-} Type_Widget;
-
-/* Pixel storage modes */
-typedef struct {
- GLint pack_alignment;
- GLint pack_row_length;
- GLint pack_skip_rows;
- GLint pack_skip_pixels;
- GLint pack_lsb_first;
- GLint pack_swap_bytes;
- GLint pack_skip_images;
- GLint pack_image_height;
-
- GLint unpack_alignment;
- GLint unpack_row_length;
- GLint unpack_skip_rows;
- GLint unpack_skip_pixels;
- GLint unpack_lsb_first;
- GLint unpack_swap_bytes;
- GLint unpack_skip_images;
- GLint unpack_image_height;
-} PixelStorageModes;
-
-static int gluBuild1DMipmapLevelsCore(GLenum, GLint,
- GLsizei,
- GLsizei,
- GLenum, GLenum, GLint, GLint, GLint,
- const void *);
-static int gluBuild2DMipmapLevelsCore(GLenum, GLint,
- GLsizei, GLsizei,
- GLsizei, GLsizei,
- GLenum, GLenum, GLint, GLint, GLint,
- const void *);
-static int gluBuild3DMipmapLevelsCore(GLenum, GLint,
- GLsizei, GLsizei, GLsizei,
- GLsizei, GLsizei, GLsizei,
- GLenum, GLenum, GLint, GLint, GLint,
- const void *);
-
-/*
- * internal function declarations
- */
-static GLfloat bytes_per_element(GLenum type);
-static GLint elements_per_group(GLenum format, GLenum type);
-static GLint is_index(GLenum format);
-static GLint image_size(GLint width, GLint height, GLenum format, GLenum type);
-static void fill_image(const PixelStorageModes *,
- GLint width, GLint height, GLenum format,
- GLenum type, GLboolean index_format,
- const void *userdata, GLushort *newimage);
-static void empty_image(const PixelStorageModes *,
- GLint width, GLint height, GLenum format,
- GLenum type, GLboolean index_format,
- const GLushort *oldimage, void *userdata);
-static void scale_internal(GLint components, GLint widthin, GLint heightin,
- const GLushort *datain,
- GLint widthout, GLint heightout,
- GLushort *dataout);
-
-static void scale_internal_ubyte(GLint components, GLint widthin,
- GLint heightin, const GLubyte *datain,
- GLint widthout, GLint heightout,
- GLubyte *dataout, GLint element_size,
- GLint ysize, GLint group_size);
-static void scale_internal_byte(GLint components, GLint widthin,
- GLint heightin, const GLbyte *datain,
- GLint widthout, GLint heightout,
- GLbyte *dataout, GLint element_size,
- GLint ysize, GLint group_size);
-static void scale_internal_ushort(GLint components, GLint widthin,
- GLint heightin, const GLushort *datain,
- GLint widthout, GLint heightout,
- GLushort *dataout, GLint element_size,
- GLint ysize, GLint group_size,
- GLint myswap_bytes);
-static void scale_internal_short(GLint components, GLint widthin,
- GLint heightin, const GLshort *datain,
- GLint widthout, GLint heightout,
- GLshort *dataout, GLint element_size,
- GLint ysize, GLint group_size,
- GLint myswap_bytes);
-static void scale_internal_uint(GLint components, GLint widthin,
- GLint heightin, const GLuint *datain,
- GLint widthout, GLint heightout,
- GLuint *dataout, GLint element_size,
- GLint ysize, GLint group_size,
- GLint myswap_bytes);
-static void scale_internal_int(GLint components, GLint widthin,
- GLint heightin, const GLint *datain,
- GLint widthout, GLint heightout,
- GLint *dataout, GLint element_size,
- GLint ysize, GLint group_size,
- GLint myswap_bytes);
-static void scale_internal_float(GLint components, GLint widthin,
- GLint heightin, const GLfloat *datain,
- GLint widthout, GLint heightout,
- GLfloat *dataout, GLint element_size,
- GLint ysize, GLint group_size,
- GLint myswap_bytes);
-
-static int checkMipmapArgs(GLenum, GLenum, GLenum);
-static GLboolean legalFormat(GLenum);
-static GLboolean legalType(GLenum);
-static GLboolean isTypePackedPixel(GLenum);
-static GLboolean isLegalFormatForPackedPixelType(GLenum, GLenum);
-static GLboolean isLegalLevels(GLint, GLint, GLint, GLint);
-static void closestFit(GLenum, GLint, GLint, GLint, GLenum, GLenum,
- GLint *, GLint *);
-
-/* all extract/shove routines must return double to handle unsigned ints */
-static GLdouble extractUbyte(int, const void *);
-static void shoveUbyte(GLdouble, int, void *);
-static GLdouble extractSbyte(int, const void *);
-static void shoveSbyte(GLdouble, int, void *);
-static GLdouble extractUshort(int, const void *);
-static void shoveUshort(GLdouble, int, void *);
-static GLdouble extractSshort(int, const void *);
-static void shoveSshort(GLdouble, int, void *);
-static GLdouble extractUint(int, const void *);
-static void shoveUint(GLdouble, int, void *);
-static GLdouble extractSint(int, const void *);
-static void shoveSint(GLdouble, int, void *);
-static GLdouble extractFloat(int, const void *);
-static void shoveFloat(GLdouble, int, void *);
-static void halveImageSlice(int, GLdouble (*)(int, const void *),
- void (*)(GLdouble, int, void *),
- GLint, GLint, GLint,
- const void *, void *,
- GLint, GLint, GLint, GLint, GLint);
-static void halveImage3D(int, GLdouble (*)(int, const void *),
- void (*)(GLdouble, int, void *),
- GLint, GLint, GLint,
- const void *, void *,
- GLint, GLint, GLint, GLint, GLint);
-
-/* packedpixel type scale routines */
-static void extract332(int,const void *, GLfloat []);
-static void shove332(const GLfloat [],int ,void *);
-static void extract233rev(int,const void *, GLfloat []);
-static void shove233rev(const GLfloat [],int ,void *);
-static void extract565(int,const void *, GLfloat []);
-static void shove565(const GLfloat [],int ,void *);
-static void extract565rev(int,const void *, GLfloat []);
-static void shove565rev(const GLfloat [],int ,void *);
-static void extract4444(int,const void *, GLfloat []);
-static void shove4444(const GLfloat [],int ,void *);
-static void extract4444rev(int,const void *, GLfloat []);
-static void shove4444rev(const GLfloat [],int ,void *);
-static void extract5551(int,const void *, GLfloat []);
-static void shove5551(const GLfloat [],int ,void *);
-static void extract1555rev(int,const void *, GLfloat []);
-static void shove1555rev(const GLfloat [],int ,void *);
-static void extract8888(int,const void *, GLfloat []);
-static void shove8888(const GLfloat [],int ,void *);
-static void extract8888rev(int,const void *, GLfloat []);
-static void shove8888rev(const GLfloat [],int ,void *);
-static void extract1010102(int,const void *, GLfloat []);
-static void shove1010102(const GLfloat [],int ,void *);
-static void extract2101010rev(int,const void *, GLfloat []);
-static void shove2101010rev(const GLfloat [],int ,void *);
-static void scaleInternalPackedPixel(int,
- void (*)(int, const void *,GLfloat []),
- void (*)(const GLfloat [],int, void *),
- GLint,GLint, const void *,
- GLint,GLint,void *,GLint,GLint,GLint);
-static void halveImagePackedPixel(int,
- void (*)(int, const void *,GLfloat []),
- void (*)(const GLfloat [],int, void *),
- GLint, GLint, const void *,
- void *, GLint, GLint, GLint);
-static void halve1DimagePackedPixel(int,
- void (*)(int, const void *,GLfloat []),
- void (*)(const GLfloat [],int, void *),
- GLint, GLint, const void *,
- void *, GLint, GLint, GLint);
-
-static void halve1Dimage_ubyte(GLint, GLuint, GLuint,const GLubyte *,
- GLubyte *, GLint, GLint, GLint);
-static void halve1Dimage_byte(GLint, GLuint, GLuint,const GLbyte *, GLbyte *,
- GLint, GLint, GLint);
-static void halve1Dimage_ushort(GLint, GLuint, GLuint, const GLushort *,
- GLushort *, GLint, GLint, GLint, GLint);
-static void halve1Dimage_short(GLint, GLuint, GLuint,const GLshort *, GLshort *,
- GLint, GLint, GLint, GLint);
-static void halve1Dimage_uint(GLint, GLuint, GLuint, const GLuint *, GLuint *,
- GLint, GLint, GLint, GLint);
-static void halve1Dimage_int(GLint, GLuint, GLuint, const GLint *, GLint *,
- GLint, GLint, GLint, GLint);
-static void halve1Dimage_float(GLint, GLuint, GLuint, const GLfloat *, GLfloat *,
- GLint, GLint, GLint, GLint);
-
-static GLint imageSize3D(GLint, GLint, GLint, GLenum,GLenum);
-static void fillImage3D(const PixelStorageModes *, GLint, GLint, GLint,GLenum,
- GLenum, GLboolean, const void *, GLushort *);
-static void emptyImage3D(const PixelStorageModes *,
- GLint, GLint, GLint, GLenum,
- GLenum, GLboolean,
- const GLushort *, void *);
-static void scaleInternal3D(GLint, GLint, GLint, GLint, const GLushort *,
- GLint, GLint, GLint, GLushort *);
-
-static void retrieveStoreModes(PixelStorageModes *psm)
-{
- glGetIntegerv(GL_UNPACK_ALIGNMENT, &psm->unpack_alignment);
- glGetIntegerv(GL_UNPACK_ROW_LENGTH, &psm->unpack_row_length);
- glGetIntegerv(GL_UNPACK_SKIP_ROWS, &psm->unpack_skip_rows);
- glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &psm->unpack_skip_pixels);
- glGetIntegerv(GL_UNPACK_LSB_FIRST, &psm->unpack_lsb_first);
- glGetIntegerv(GL_UNPACK_SWAP_BYTES, &psm->unpack_swap_bytes);
-
- glGetIntegerv(GL_PACK_ALIGNMENT, &psm->pack_alignment);
- glGetIntegerv(GL_PACK_ROW_LENGTH, &psm->pack_row_length);
- glGetIntegerv(GL_PACK_SKIP_ROWS, &psm->pack_skip_rows);
- glGetIntegerv(GL_PACK_SKIP_PIXELS, &psm->pack_skip_pixels);
- glGetIntegerv(GL_PACK_LSB_FIRST, &psm->pack_lsb_first);
- glGetIntegerv(GL_PACK_SWAP_BYTES, &psm->pack_swap_bytes);
-}
-
-static void retrieveStoreModes3D(PixelStorageModes *psm)
-{
- glGetIntegerv(GL_UNPACK_ALIGNMENT, &psm->unpack_alignment);
- glGetIntegerv(GL_UNPACK_ROW_LENGTH, &psm->unpack_row_length);
- glGetIntegerv(GL_UNPACK_SKIP_ROWS, &psm->unpack_skip_rows);
- glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &psm->unpack_skip_pixels);
- glGetIntegerv(GL_UNPACK_LSB_FIRST, &psm->unpack_lsb_first);
- glGetIntegerv(GL_UNPACK_SWAP_BYTES, &psm->unpack_swap_bytes);
- glGetIntegerv(GL_UNPACK_SKIP_IMAGES, &psm->unpack_skip_images);
- glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, &psm->unpack_image_height);
-
- glGetIntegerv(GL_PACK_ALIGNMENT, &psm->pack_alignment);
- glGetIntegerv(GL_PACK_ROW_LENGTH, &psm->pack_row_length);
- glGetIntegerv(GL_PACK_SKIP_ROWS, &psm->pack_skip_rows);
- glGetIntegerv(GL_PACK_SKIP_PIXELS, &psm->pack_skip_pixels);
- glGetIntegerv(GL_PACK_LSB_FIRST, &psm->pack_lsb_first);
- glGetIntegerv(GL_PACK_SWAP_BYTES, &psm->pack_swap_bytes);
- glGetIntegerv(GL_PACK_SKIP_IMAGES, &psm->pack_skip_images);
- glGetIntegerv(GL_PACK_IMAGE_HEIGHT, &psm->pack_image_height);
-}
-
-static int computeLog(GLuint value)
-{
- int i;
-
- i = 0;
-
- /* Error! */
- if (value == 0) return -1;
-
- for (;;) {
- if (value & 1) {
- /* Error ! */
- if (value != 1) return -1;
- return i;
- }
- value = value >> 1;
- i++;
- }
-}
-
-/*
-** Compute the nearest power of 2 number. This algorithm is a little
-** strange, but it works quite well.
-*/
-static int nearestPower(GLuint value)
-{
- int i;
-
- i = 1;
-
- /* Error! */
- if (value == 0) return -1;
-
- for (;;) {
- if (value == 1) {
- return i;
- } else if (value == 3) {
- return i*4;
- }
- value = value >> 1;
- i *= 2;
- }
-}
-
-#define __GLU_SWAP_2_BYTES(s)\
-(GLushort)(((GLushort)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
-
-#define __GLU_SWAP_4_BYTES(s)\
-(GLuint)(((GLuint)((const GLubyte*)(s))[3])<<24 | \
- ((GLuint)((const GLubyte*)(s))[2])<<16 | \
- ((GLuint)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0])
-
-static void halveImage(GLint components, GLuint width, GLuint height,
- const GLushort *datain, GLushort *dataout)
-{
- int i, j, k;
- int newwidth, newheight;
- int delta;
- GLushort *s;
- const GLushort *t;
-
- newwidth = width / 2;
- newheight = height / 2;
- delta = width * components;
- s = dataout;
- t = datain;
-
- /* Piece o' cake! */
- for (i = 0; i < newheight; i++) {
- for (j = 0; j < newwidth; j++) {
- for (k = 0; k < components; k++) {
- s[0] = (t[0] + t[components] + t[delta] +
- t[delta+components] + 2) / 4;
- s++; t++;
- }
- t += components;
- }
- t += delta;
- }
-}
-
-static void halveImage_ubyte(GLint components, GLuint width, GLuint height,
- const GLubyte *datain, GLubyte *dataout,
- GLint element_size, GLint ysize, GLint group_size)
-{
- int i, j, k;
- int newwidth, newheight;
- int padBytes;
- GLubyte *s;
- const char *t;
-
- /* handle case where there is only 1 column/row */
- if (width == 1 || height == 1) {
- assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
- halve1Dimage_ubyte(components,width,height,datain,dataout,
- element_size,ysize,group_size);
- return;
- }
-
- newwidth = width / 2;
- newheight = height / 2;
- padBytes = ysize - (width*group_size);
- s = dataout;
- t = (const char *)datain;
-
- /* Piece o' cake! */
- for (i = 0; i < newheight; i++) {
- for (j = 0; j < newwidth; j++) {
- for (k = 0; k < components; k++) {
- s[0] = (*(const GLubyte*)t +
- *(const GLubyte*)(t+group_size) +
- *(const GLubyte*)(t+ysize) +
- *(const GLubyte*)(t+ysize+group_size) + 2) / 4;
- s++; t += element_size;
- }
- t += group_size;
- }
- t += padBytes;
- t += ysize;
- }
-}
-
-/* */
-static void halve1Dimage_ubyte(GLint components, GLuint width, GLuint height,
- const GLubyte *dataIn, GLubyte *dataOut,
- GLint element_size, GLint ysize,
- GLint group_size)
-{
- GLint halfWidth= width / 2;
- GLint halfHeight= height / 2;
- const char *src= (const char *) dataIn;
- GLubyte *dest= dataOut;
- int jj;
-
- assert(width == 1 || height == 1); /* must be 1D */
- assert(width != height); /* can't be square */
-
- if (height == 1) { /* 1 row */
- assert(width != 1); /* widthxheight can't be 1x1 */
- halfHeight= 1;
-
- for (jj= 0; jj< halfWidth; jj++) {
- int kk;
- for (kk= 0; kk< components; kk++) {
- *dest= (*(const GLubyte*)src +
- *(const GLubyte*)(src+group_size)) / 2;
-
- src+= element_size;
- dest++;
- }
- src+= group_size; /* skip to next 2 */
- }
- {
- int padBytes= ysize - (width*group_size);
- src+= padBytes; /* for assertion only */
- }
- }
- else if (width == 1) { /* 1 column */
- int padBytes= ysize - (width * group_size);
- assert(height != 1); /* widthxheight can't be 1x1 */
- halfWidth= 1;
- /* one vertical column with possible pad bytes per row */
- /* average two at a time */
-
- for (jj= 0; jj< halfHeight; jj++) {
- int kk;
- for (kk= 0; kk< components; kk++) {
- *dest= (*(const GLubyte*)src + *(const GLubyte*)(src+ysize)) / 2;
-
- src+= element_size;
- dest++;
- }
- src+= padBytes; /* add pad bytes, if any, to get to end to row */
- src+= ysize;
- }
- }
-
- assert(src == &((const char *)dataIn)[ysize*height]);
- assert((char *)dest == &((char *)dataOut)
- [components * element_size * halfWidth * halfHeight]);
-} /* halve1Dimage_ubyte() */
-
-static void halveImage_byte(GLint components, GLuint width, GLuint height,
- const GLbyte *datain, GLbyte *dataout,
- GLint element_size,
- GLint ysize, GLint group_size)
-{
- int i, j, k;
- int newwidth, newheight;
- int padBytes;
- GLbyte *s;
- const char *t;
-
- /* handle case where there is only 1 column/row */
- if (width == 1 || height == 1) {
- assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
- halve1Dimage_byte(components,width,height,datain,dataout,
- element_size,ysize,group_size);
- return;
- }
-
- newwidth = width / 2;
- newheight = height / 2;
- padBytes = ysize - (width*group_size);
- s = dataout;
- t = (const char *)datain;
-
- /* Piece o' cake! */
- for (i = 0; i < newheight; i++) {
- for (j = 0; j < newwidth; j++) {
- for (k = 0; k < components; k++) {
- s[0] = (*(const GLbyte*)t +
- *(const GLbyte*)(t+group_size) +
- *(const GLbyte*)(t+ysize) +
- *(const GLbyte*)(t+ysize+group_size) + 2) / 4;
- s++; t += element_size;
- }
- t += group_size;
- }
- t += padBytes;
- t += ysize;
- }
-}
-
-static void halve1Dimage_byte(GLint components, GLuint width, GLuint height,
- const GLbyte *dataIn, GLbyte *dataOut,
- GLint element_size,GLint ysize, GLint group_size)
-{
- GLint halfWidth= width / 2;
- GLint halfHeight= height / 2;
- const char *src= (const char *) dataIn;
- GLbyte *dest= dataOut;
- int jj;
-
- assert(width == 1 || height == 1); /* must be 1D */
- assert(width != height); /* can't be square */
-
- if (height == 1) { /* 1 row */
- assert(width != 1); /* widthxheight can't be 1x1 */
- halfHeight= 1;
-
- for (jj= 0; jj< halfWidth; jj++) {
- int kk;
- for (kk= 0; kk< components; kk++) {
- *dest= (*(const GLbyte*)src + *(const GLbyte*)(src+group_size)) / 2;
-
- src+= element_size;
- dest++;
- }
- src+= group_size; /* skip to next 2 */
- }
- {
- int padBytes= ysize - (width*group_size);
- src+= padBytes; /* for assertion only */
- }
- }
- else if (width == 1) { /* 1 column */
- int padBytes= ysize - (width * group_size);
- assert(height != 1); /* widthxheight can't be 1x1 */
- halfWidth= 1;
- /* one vertical column with possible pad bytes per row */
- /* average two at a time */
-
- for (jj= 0; jj< halfHeight; jj++) {
- int kk;
- for (kk= 0; kk< components; kk++) {
- *dest= (*(const GLbyte*)src + *(const GLbyte*)(src+ysize)) / 2;
-
- src+= element_size;
- dest++;
- }
- src+= padBytes; /* add pad bytes, if any, to get to end to row */
- src+= ysize;
- }
-
- assert(src == &((const char *)dataIn)[ysize*height]);
- }
-
- assert((char *)dest == &((char *)dataOut)
- [components * element_size * halfWidth * halfHeight]);
-} /* halve1Dimage_byte() */
-
-static void halveImage_ushort(GLint components, GLuint width, GLuint height,
- const GLushort *datain, GLushort *dataout,
- GLint element_size, GLint ysize, GLint group_size,
- GLint myswap_bytes)
-{
- int i, j, k;
- int newwidth, newheight;
- int padBytes;
- GLushort *s;
- const char *t;
-
- /* handle case where there is only 1 column/row */
- if (width == 1 || height == 1) {
- assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
- halve1Dimage_ushort(components,width,height,datain,dataout,
- element_size,ysize,group_size, myswap_bytes);
- return;
- }
-
- newwidth = width / 2;
- newheight = height / 2;
- padBytes = ysize - (width*group_size);
- s = dataout;
- t = (const char *)datain;
-
- /* Piece o' cake! */
- if (!myswap_bytes)
- for (i = 0; i < newheight; i++) {
- for (j = 0; j < newwidth; j++) {
- for (k = 0; k < components; k++) {
- s[0] = (*(const GLushort*)t +
- *(const GLushort*)(t+group_size) +
- *(const GLushort*)(t+ysize) +
- *(const GLushort*)(t+ysize+group_size) + 2) / 4;
- s++; t += element_size;
- }
- t += group_size;
- }
- t += padBytes;
- t += ysize;
- }
- else
- for (i = 0; i < newheight; i++) {
- for (j = 0; j < newwidth; j++) {
- for (k = 0; k < components; k++) {
- s[0] = (__GLU_SWAP_2_BYTES(t) +
- __GLU_SWAP_2_BYTES(t+group_size) +
- __GLU_SWAP_2_BYTES(t+ysize) +
- __GLU_SWAP_2_BYTES(t+ysize+group_size)+ 2)/4;
- s++; t += element_size;
- }
- t += group_size;
- }
- t += padBytes;
- t += ysize;
- }
-}
-
-static void halve1Dimage_ushort(GLint components, GLuint width, GLuint height,
- const GLushort *dataIn, GLushort *dataOut,
- GLint element_size, GLint ysize,
- GLint group_size, GLint myswap_bytes)
-{
- GLint halfWidth= width / 2;
- GLint halfHeight= height / 2;
- const char *src= (const char *) dataIn;
- GLushort *dest= dataOut;
- int jj;
-
- assert(width == 1 || height == 1); /* must be 1D */
- assert(width != height); /* can't be square */
-
- if (height == 1) { /* 1 row */
- assert(width != 1); /* widthxheight can't be 1x1 */
- halfHeight= 1;
-
- for (jj= 0; jj< halfWidth; jj++) {
- int kk;
- for (kk= 0; kk< components; kk++) {
-#define BOX2 2
- GLushort ushort[BOX2];
- if (myswap_bytes) {
- ushort[0]= __GLU_SWAP_2_BYTES(src);
- ushort[1]= __GLU_SWAP_2_BYTES(src+group_size);
- }
- else {
- ushort[0]= *(const GLushort*)src;
- ushort[1]= *(const GLushort*)(src+group_size);
- }
-
- *dest= (ushort[0] + ushort[1]) / 2;
- src+= element_size;
- dest++;
- }
- src+= group_size; /* skip to next 2 */
- }
- {
- int padBytes= ysize - (width*group_size);
- src+= padBytes; /* for assertion only */
- }
- }
- else if (width == 1) { /* 1 column */
- int padBytes= ysize - (width * group_size);
- assert(height != 1); /* widthxheight can't be 1x1 */
- halfWidth= 1;
- /* one vertical column with possible pad bytes per row */
- /* average two at a time */
-
- for (jj= 0; jj< halfHeight; jj++) {
- int kk;
- for (kk= 0; kk< components; kk++) {
-#define BOX2 2
- GLushort ushort[BOX2];
- if (myswap_bytes) {
- ushort[0]= __GLU_SWAP_2_BYTES(src);
- ushort[1]= __GLU_SWAP_2_BYTES(src+ysize);
- }
- else {
- ushort[0]= *(const GLushort*)src;
- ushort[1]= *(const GLushort*)(src+ysize);
- }
- *dest= (ushort[0] + ushort[1]) / 2;
-
- src+= element_size;
- dest++;
- }
- src+= padBytes; /* add pad bytes, if any, to get to end to row */
- src+= ysize;
- }
-
- assert(src == &((const char *)dataIn)[ysize*height]);
- }
-
- assert((char *)dest == &((char *)dataOut)
- [components * element_size * halfWidth * halfHeight]);
-
-} /* halve1Dimage_ushort() */
-
-
-static void halveImage_short(GLint components, GLuint width, GLuint height,
- const GLshort *datain, GLshort *dataout,
- GLint element_size, GLint ysize, GLint group_size,
- GLint myswap_bytes)
-{
- int i, j, k;
- int newwidth, newheight;
- int padBytes;
- GLshort *s;
- const char *t;
-
- /* handle case where there is only 1 column/row */
- if (width == 1 || height == 1) {
- assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
- halve1Dimage_short(components,width,height,datain,dataout,
- element_size,ysize,group_size, myswap_bytes);
- return;
- }
-
- newwidth = width / 2;
- newheight = height / 2;
- padBytes = ysize - (width*group_size);
- s = dataout;
- t = (const char *)datain;
-
- /* Piece o' cake! */
- if (!myswap_bytes)
- for (i = 0; i < newheight; i++) {
- for (j = 0; j < newwidth; j++) {
- for (k = 0; k < components; k++) {
- s[0] = (*(const GLshort*)t +
- *(const GLshort*)(t+group_size) +
- *(const GLshort*)(t+ysize) +
- *(const GLshort*)(t+ysize+group_size) + 2) / 4;
- s++; t += element_size;
- }
- t += group_size;
- }
- t += padBytes;
- t += ysize;
- }
- else
- for (i = 0; i < newheight; i++) {
- for (j = 0; j < newwidth; j++) {
- for (k = 0; k < components; k++) {
- GLushort b;
- GLint buf;
- b = __GLU_SWAP_2_BYTES(t);
- buf = *(const GLshort*)&b;
- b = __GLU_SWAP_2_BYTES(t+group_size);
- buf += *(const GLshort*)&b;
- b = __GLU_SWAP_2_BYTES(t+ysize);
- buf += *(const GLshort*)&b;
- b = __GLU_SWAP_2_BYTES(t+ysize+group_size);
- buf += *(const GLshort*)&b;
- s[0] = (GLshort)((buf+2)/4);
- s++; t += element_size;
- }
- t += group_size;
- }
- t += padBytes;
- t += ysize;
- }
-}
-
-static void halve1Dimage_short(GLint components, GLuint width, GLuint height,
- const GLshort *dataIn, GLshort *dataOut,
- GLint element_size, GLint ysize,
- GLint group_size, GLint myswap_bytes)
-{
- GLint halfWidth= width / 2;
- GLint halfHeight= height / 2;
- const char *src= (const char *) dataIn;
- GLshort *dest= dataOut;
- int jj;
-
- assert(width == 1 || height == 1); /* must be 1D */
- assert(width != height); /* can't be square */
-
- if (height == 1) { /* 1 row */
- assert(width != 1); /* widthxheight can't be 1x1 */
- halfHeight= 1;
-
- for (jj= 0; jj< halfWidth; jj++) {
- int kk;
- for (kk= 0; kk< components; kk++) {
-#define BOX2 2
- GLshort sshort[BOX2];
- if (myswap_bytes) {
- sshort[0]= __GLU_SWAP_2_BYTES(src);
- sshort[1]= __GLU_SWAP_2_BYTES(src+group_size);
- }
- else {
- sshort[0]= *(const GLshort*)src;
- sshort[1]= *(const GLshort*)(src+group_size);
- }
-
- *dest= (sshort[0] + sshort[1]) / 2;
- src+= element_size;
- dest++;
- }
- src+= group_size; /* skip to next 2 */
- }
- {
- int padBytes= ysize - (width*group_size);
- src+= padBytes; /* for assertion only */
- }
- }
- else if (width == 1) { /* 1 column */
- int padBytes= ysize - (width * group_size);
- assert(height != 1); /* widthxheight can't be 1x1 */
- halfWidth= 1;
- /* one vertical column with possible pad bytes per row */
- /* average two at a time */
-
- for (jj= 0; jj< halfHeight; jj++) {
- int kk;
- for (kk= 0; kk< components; kk++) {
-#define BOX2 2
- GLshort sshort[BOX2];
- if (myswap_bytes) {
- sshort[0]= __GLU_SWAP_2_BYTES(src);
- sshort[1]= __GLU_SWAP_2_BYTES(src+ysize);
- }
- else {
- sshort[0]= *(const GLshort*)src;
- sshort[1]= *(const GLshort*)(src+ysize);
- }
- *dest= (sshort[0] + sshort[1]) / 2;
-
- src+= element_size;
- dest++;
- }
- src+= padBytes; /* add pad bytes, if any, to get to end to row */
- src+= ysize;
- }
-
- assert(src == &((const char *)dataIn)[ysize*height]);
- }
-
- assert((char *)dest == &((char *)dataOut)
- [components * element_size * halfWidth * halfHeight]);
-
-} /* halve1Dimage_short() */
-
-
-static void halveImage_uint(GLint components, GLuint width, GLuint height,
- const GLuint *datain, GLuint *dataout,
- GLint element_size, GLint ysize, GLint group_size,
- GLint myswap_bytes)
-{
- int i, j, k;
- int newwidth, newheight;
- int padBytes;
- GLuint *s;
- const char *t;
-
- /* handle case where there is only 1 column/row */
- if (width == 1 || height == 1) {
- assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
- halve1Dimage_uint(components,width,height,datain,dataout,
- element_size,ysize,group_size, myswap_bytes);
- return;
- }
-
- newwidth = width / 2;
- newheight = height / 2;
- padBytes = ysize - (width*group_size);
- s = dataout;
- t = (const char *)datain;
-
- /* Piece o' cake! */
- if (!myswap_bytes)
- for (i = 0; i < newheight; i++) {
- for (j = 0; j < newwidth; j++) {
- for (k = 0; k < components; k++) {
- /* need to cast to double to hold large unsigned ints */
- s[0] = ((double)*(const GLuint*)t +
- (double)*(const GLuint*)(t+group_size) +
- (double)*(const GLuint*)(t+ysize) +
- (double)*(const GLuint*)(t+ysize+group_size))/4 + 0.5;
- s++; t += element_size;
-
- }
- t += group_size;
- }
- t += padBytes;
- t += ysize;
- }
- else
- for (i = 0; i < newheight; i++) {
- for (j = 0; j < newwidth; j++) {
- for (k = 0; k < components; k++) {
- /* need to cast to double to hold large unsigned ints */
- GLdouble buf;
- buf = (GLdouble)__GLU_SWAP_4_BYTES(t) +
- (GLdouble)__GLU_SWAP_4_BYTES(t+group_size) +
- (GLdouble)__GLU_SWAP_4_BYTES(t+ysize) +
- (GLdouble)__GLU_SWAP_4_BYTES(t+ysize+group_size);
- s[0] = (GLuint)(buf/4 + 0.5);
-
- s++; t += element_size;
- }
- t += group_size;
- }
- t += padBytes;
- t += ysize;
- }
-}
-
-/* */
-static void halve1Dimage_uint(GLint components, GLuint width, GLuint height,
- const GLuint *dataIn, GLuint *dataOut,
- GLint element_size, GLint ysize,
- GLint group_size, GLint myswap_bytes)
-{
- GLint halfWidth= width / 2;
- GLint halfHeight= height / 2;
- const char *src= (const char *) dataIn;
- GLuint *dest= dataOut;
- int jj;
-
- assert(width == 1 || height == 1); /* must be 1D */
- assert(width != height); /* can't be square */
-
- if (height == 1) { /* 1 row */
- assert(width != 1); /* widthxheight can't be 1x1 */
- halfHeight= 1;
-
- for (jj= 0; jj< halfWidth; jj++) {
- int kk;
- for (kk= 0; kk< components; kk++) {
-#define BOX2 2
- GLuint uint[BOX2];
- if (myswap_bytes) {
- uint[0]= __GLU_SWAP_4_BYTES(src);
- uint[1]= __GLU_SWAP_4_BYTES(src+group_size);
- }
- else {
- uint[0]= *(const GLuint*)src;
- uint[1]= *(const GLuint*)(src+group_size);
- }
- *dest= ((double)uint[0]+(double)uint[1])/2.0;
-
- src+= element_size;
- dest++;
- }
- src+= group_size; /* skip to next 2 */
- }
- {
- int padBytes= ysize - (width*group_size);
- src+= padBytes; /* for assertion only */
- }
- }
- else if (width == 1) { /* 1 column */
- int padBytes= ysize - (width * group_size);
- assert(height != 1); /* widthxheight can't be 1x1 */
- halfWidth= 1;
- /* one vertical column with possible pad bytes per row */
- /* average two at a time */
-
- for (jj= 0; jj< halfHeight; jj++) {
- int kk;
- for (kk= 0; kk< components; kk++) {
-#define BOX2 2
- GLuint uint[BOX2];
- if (myswap_bytes) {
- uint[0]= __GLU_SWAP_4_BYTES(src);
- uint[1]= __GLU_SWAP_4_BYTES(src+ysize);
- }
- else {
- uint[0]= *(const GLuint*)src;
- uint[1]= *(const GLuint*)(src+ysize);
- }
- *dest= ((double)uint[0]+(double)uint[1])/2.0;
-
- src+= element_size;
- dest++;
- }
- src+= padBytes; /* add pad bytes, if any, to get to end to row */
- src+= ysize;
- }
-
- assert(src == &((const char *)dataIn)[ysize*height]);
- }
-
- assert((char *)dest == &((char *)dataOut)
- [components * element_size * halfWidth * halfHeight]);
-
-} /* halve1Dimage_uint() */
-
-static void halveImage_int(GLint components, GLuint width, GLuint height,
- const GLint *datain, GLint *dataout, GLint element_size,
- GLint ysize, GLint group_size, GLint myswap_bytes)
-{
- int i, j, k;
- int newwidth, newheight;
- int padBytes;
- GLint *s;
- const char *t;
-
- /* handle case where there is only 1 column/row */
- if (width == 1 || height == 1) {
- assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
- halve1Dimage_int(components,width,height,datain,dataout,
- element_size,ysize,group_size, myswap_bytes);
- return;
- }
-
- newwidth = width / 2;
- newheight = height / 2;
- padBytes = ysize - (width*group_size);
- s = dataout;
- t = (const char *)datain;
-
- /* Piece o' cake! */
- if (!myswap_bytes)
- for (i = 0; i < newheight; i++) {
- for (j = 0; j < newwidth; j++) {
- for (k = 0; k < components; k++) {
- s[0] = ((float)*(const GLint*)t +
- (float)*(const GLint*)(t+group_size) +
- (float)*(const GLint*)(t+ysize) +
- (float)*(const GLint*)(t+ysize+group_size))/4 + 0.5;
- s++; t += element_size;
- }
- t += group_size;
- }
- t += padBytes;
- t += ysize;
- }
- else
- for (i = 0; i < newheight; i++) {
- for (j = 0; j < newwidth; j++) {
- for (k = 0; k < components; k++) {
- GLuint b;
- GLfloat buf;
- b = __GLU_SWAP_4_BYTES(t);
- buf = *(GLint*)&b;
- b = __GLU_SWAP_4_BYTES(t+group_size);
- buf += *(GLint*)&b;
- b = __GLU_SWAP_4_BYTES(t+ysize);
- buf += *(GLint*)&b;
- b = __GLU_SWAP_4_BYTES(t+ysize+group_size);
- buf += *(GLint*)&b;
- s[0] = (GLint)(buf/4 + 0.5);
-
- s++; t += element_size;
- }
- t += group_size;
- }
- t += padBytes;
- t += ysize;
- }
-}
-
-/* */
-static void halve1Dimage_int(GLint components, GLuint width, GLuint height,
- const GLint *dataIn, GLint *dataOut,
- GLint element_size, GLint ysize,
- GLint group_size, GLint myswap_bytes)
-{
- GLint halfWidth= width / 2;
- GLint halfHeight= height / 2;
- const char *src= (const char *) dataIn;
- GLint *dest= dataOut;
- int jj;
-
- assert(width == 1 || height == 1); /* must be 1D */
- assert(width != height); /* can't be square */
-
- if (height == 1) { /* 1 row */
- assert(width != 1); /* widthxheight can't be 1x1 */
- halfHeight= 1;
-
- for (jj= 0; jj< halfWidth; jj++) {
- int kk;
- for (kk= 0; kk< components; kk++) {
-#define BOX2 2
- GLuint uint[BOX2];
- if (myswap_bytes) {
- uint[0]= __GLU_SWAP_4_BYTES(src);
- uint[1]= __GLU_SWAP_4_BYTES(src+group_size);
- }
- else {
- uint[0]= *(const GLuint*)src;
- uint[1]= *(const GLuint*)(src+group_size);
- }
- *dest= ((float)uint[0]+(float)uint[1])/2.0;
-
- src+= element_size;
- dest++;
- }
- src+= group_size; /* skip to next 2 */
- }
- {
- int padBytes= ysize - (width*group_size);
- src+= padBytes; /* for assertion only */
- }
- }
- else if (width == 1) { /* 1 column */
- int padBytes= ysize - (width * group_size);
- assert(height != 1); /* widthxheight can't be 1x1 */
- halfWidth= 1;
- /* one vertical column with possible pad bytes per row */
- /* average two at a time */
-
- for (jj= 0; jj< halfHeight; jj++) {
- int kk;
- for (kk= 0; kk< components; kk++) {
-#define BOX2 2
- GLuint uint[BOX2];
- if (myswap_bytes) {
- uint[0]= __GLU_SWAP_4_BYTES(src);
- uint[1]= __GLU_SWAP_4_BYTES(src+ysize);
- }
- else {
- uint[0]= *(const GLuint*)src;
- uint[1]= *(const GLuint*)(src+ysize);
- }
- *dest= ((float)uint[0]+(float)uint[1])/2.0;
-
- src+= element_size;
- dest++;
- }
- src+= padBytes; /* add pad bytes, if any, to get to end to row */
- src+= ysize;
- }
-
- assert(src == &((const char *)dataIn)[ysize*height]);
- }
-
- assert((char *)dest == &((char *)dataOut)
- [components * element_size * halfWidth * halfHeight]);
-
-} /* halve1Dimage_int() */
-
-
-static void halveImage_float(GLint components, GLuint width, GLuint height,
- const GLfloat *datain, GLfloat *dataout,
- GLint element_size, GLint ysize, GLint group_size,
- GLint myswap_bytes)
-{
- int i, j, k;
- int newwidth, newheight;
- int padBytes;
- GLfloat *s;
- const char *t;
-
- /* handle case where there is only 1 column/row */
- if (width == 1 || height == 1) {
- assert( !(width == 1 && height == 1) ); /* can't be 1x1 */
- halve1Dimage_float(components,width,height,datain,dataout,
- element_size,ysize,group_size, myswap_bytes);
- return;
- }
-
- newwidth = width / 2;
- newheight = height / 2;
- padBytes = ysize - (width*group_size);
- s = dataout;
- t = (const char *)datain;
-
- /* Piece o' cake! */
- if (!myswap_bytes)
- for (i = 0; i < newheight; i++) {
- for (j = 0; j < newwidth; j++) {
- for (k = 0; k < components; k++) {
- s[0] = (*(const GLfloat*)t +
- *(const GLfloat*)(t+group_size) +
- *(const GLfloat*)(t+ysize) +
- *(const GLfloat*)(t+ysize+group_size)) / 4;
- s++; t += element_size;
- }
- t += group_size;
- }
- t += padBytes;
- t += ysize;
- }
- else
- for (i = 0; i < newheight; i++) {
- for (j = 0; j < newwidth; j++) {
- for (k = 0; k < components; k++) {
- union { GLuint b; GLfloat f; } swapbuf;
- swapbuf.b = __GLU_SWAP_4_BYTES(t);
- s[0] = swapbuf.f;
- swapbuf.b = __GLU_SWAP_4_BYTES(t+group_size);
- s[0] += swapbuf.f;
- swapbuf.b = __GLU_SWAP_4_BYTES(t+ysize);
- s[0] += swapbuf.f;
- swapbuf.b = __GLU_SWAP_4_BYTES(t+ysize+group_size);
- s[0] += swapbuf.f;
- s[0] /= 4;
- s++; t += element_size;
- }
- t += group_size;
- }
- t += padBytes;
- t += ysize;
- }
-}
-
-/* */
-static void halve1Dimage_float(GLint components, GLuint width, GLuint height,
- const GLfloat *dataIn, GLfloat *dataOut,
- GLint element_size, GLint ysize,
- GLint group_size, GLint myswap_bytes)
-{
- GLint halfWidth= width / 2;
- GLint halfHeight= height / 2;
- const char *src= (const char *) dataIn;
- GLfloat *dest= dataOut;
- int jj;
-
- assert(width == 1 || height == 1); /* must be 1D */
- assert(width != height); /* can't be square */
-
- if (height == 1) { /* 1 row */
- assert(width != 1); /* widthxheight can't be 1x1 */
- halfHeight= 1;
-
- for (jj= 0; jj< halfWidth; jj++) {
- int kk;
- for (kk= 0; kk< components; kk++) {
-#define BOX2 2
- GLfloat sfloat[BOX2];
- if (myswap_bytes) {
- sfloat[0]= __GLU_SWAP_4_BYTES(src);
- sfloat[1]= __GLU_SWAP_4_BYTES(src+group_size);
- }
- else {
- sfloat[0]= *(const GLfloat*)src;
- sfloat[1]= *(const GLfloat*)(src+group_size);
- }
-
- *dest= (sfloat[0] + sfloat[1]) / 2.0;
- src+= element_size;
- dest++;
- }
- src+= group_size; /* skip to next 2 */
- }
- {
- int padBytes= ysize - (width*group_size);
- src+= padBytes; /* for assertion only */
- }
- }
- else if (width == 1) { /* 1 column */
- int padBytes= ysize - (width * group_size);
- assert(height != 1); /* widthxheight can't be 1x1 */
- halfWidth= 1;
- /* one vertical column with possible pad bytes per row */
- /* average two at a time */
-
- for (jj= 0; jj< halfHeight; jj++) {
- int kk;
- for (kk= 0; kk< components; kk++) {
-#define BOX2 2
- GLfloat sfloat[BOX2];
- if (myswap_bytes) {
- sfloat[0]= __GLU_SWAP_4_BYTES(src);
- sfloat[1]= __GLU_SWAP_4_BYTES(src+ysize);
- }
- else {
- sfloat[0]= *(const GLfloat*)src;
- sfloat[1]= *(const GLfloat*)(src+ysize);
- }
- *dest= (sfloat[0] + sfloat[1]) / 2.0;
-
- src+= element_size;
- dest++;
- }
- src+= padBytes; /* add pad bytes, if any, to get to end to row */
- src+= ysize; /* skip to odd row */
- }
- }
-
- assert(src == &((const char *)dataIn)[ysize*height]);
- assert((char *)dest == &((char *)dataOut)
- [components * element_size * halfWidth * halfHeight]);
-} /* halve1Dimage_float() */
-
-static void scale_internal(GLint components, GLint widthin, GLint heightin,
- const GLushort *datain,
- GLint widthout, GLint heightout,
- GLushort *dataout)
-{
- float x, lowx, highx, convx, halfconvx;
- float y, lowy, highy, convy, halfconvy;
- float xpercent,ypercent;
- float percent;
- /* Max components in a format is 4, so... */
- float totals[4];
- float area;
- int i,j,k,yint,xint,xindex,yindex;
- int temp;
-
- if (widthin == widthout*2 && heightin == heightout*2) {
- halveImage(components, widthin, heightin, datain, dataout);
- return;
- }
- convy = (float) heightin/heightout;
- convx = (float) widthin/widthout;
- halfconvx = convx/2;
- halfconvy = convy/2;
- for (i = 0; i < heightout; i++) {
- y = convy * (i+0.5);
- if (heightin > heightout) {
- highy = y + halfconvy;
- lowy = y - halfconvy;
- } else {
- highy = y + 0.5;
- lowy = y - 0.5;
- }
- for (j = 0; j < widthout; j++) {
- x = convx * (j+0.5);
- if (widthin > widthout) {
- highx = x + halfconvx;
- lowx = x - halfconvx;
- } else {
- highx = x + 0.5;
- lowx = x - 0.5;
- }
-
- /*
- ** Ok, now apply box filter to box that goes from (lowx, lowy)
- ** to (highx, highy) on input data into this pixel on output
- ** data.
- */
- totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
- area = 0.0;
-
- y = lowy;
- yint = floor(y);
- while (y < highy) {
- yindex = (yint + heightin) % heightin;
- if (highy < yint+1) {
- ypercent = highy - y;
- } else {
- ypercent = yint+1 - y;
- }
-
- x = lowx;
- xint = floor(x);
-
- while (x < highx) {
- xindex = (xint + widthin) % widthin;
- if (highx < xint+1) {
- xpercent = highx - x;
- } else {
- xpercent = xint+1 - x;
- }
-
- percent = xpercent * ypercent;
- area += percent;
- temp = (xindex + (yindex * widthin)) * components;
- for (k = 0; k < components; k++) {
- totals[k] += datain[temp + k] * percent;
- }
-
- xint++;
- x = xint;
- }
- yint++;
- y = yint;
- }
-
- temp = (j + (i * widthout)) * components;
- for (k = 0; k < components; k++) {
- /* totals[] should be rounded in the case of enlarging an RGB
- * ramp when the type is 332 or 4444
- */
- dataout[temp + k] = (totals[k]+0.5)/area;
- }
- }
- }
-}
-
-static void scale_internal_ubyte(GLint components, GLint widthin,
- GLint heightin, const GLubyte *datain,
- GLint widthout, GLint heightout,
- GLubyte *dataout, GLint element_size,
- GLint ysize, GLint group_size)
-{
- float convx;
- float convy;
- float percent;
- /* Max components in a format is 4, so... */
- float totals[4];
- float area;
- int i,j,k,xindex;
-
- const char *temp, *temp0;
- const char *temp_index;
- int outindex;
-
- int lowx_int, highx_int, lowy_int, highy_int;
- float x_percent, y_percent;
- float lowx_float, highx_float, lowy_float, highy_float;
- float convy_float, convx_float;
- int convy_int, convx_int;
- int l, m;
- const char *left, *right;
-
- if (widthin == widthout*2 && heightin == heightout*2) {
- halveImage_ubyte(components, widthin, heightin,
- (const GLubyte *)datain, (GLubyte *)dataout,
- element_size, ysize, group_size);
- return;
- }
- convy = (float) heightin/heightout;
- convx = (float) widthin/widthout;
- convy_int = floor(convy);
- convy_float = convy - convy_int;
- convx_int = floor(convx);
- convx_float = convx - convx_int;
-
- area = convx * convy;
-
- lowy_int = 0;
- lowy_float = 0;
- highy_int = convy_int;
- highy_float = convy_float;
-
- for (i = 0; i < heightout; i++) {
- /* Clamp here to be sure we don't read beyond input buffer. */
- if (highy_int >= heightin)
- highy_int = heightin - 1;
- lowx_int = 0;
- lowx_float = 0;
- highx_int = convx_int;
- highx_float = convx_float;
-
- for (j = 0; j < widthout; j++) {
-
- /*
- ** Ok, now apply box filter to box that goes from (lowx, lowy)
- ** to (highx, highy) on input data into this pixel on output
- ** data.
- */
- totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
-
- /* calculate the value for pixels in the 1st row */
- xindex = lowx_int*group_size;
- if((highy_int>lowy_int) && (highx_int>lowx_int)) {
-
- y_percent = 1-lowy_float;
- temp = (const char *)datain + xindex + lowy_int * ysize;
- percent = y_percent * (1-lowx_float);
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLubyte)(*(temp_index)) * percent;
- }
- left = temp;
- for(l = lowx_int+1; l < highx_int; l++) {
- temp += group_size;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLubyte)(*(temp_index)) * y_percent;
- }
- }
- temp += group_size;
- right = temp;
- percent = y_percent * highx_float;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLubyte)(*(temp_index)) * percent;
- }
-
- /* calculate the value for pixels in the last row */
- y_percent = highy_float;
- percent = y_percent * (1-lowx_float);
- temp = (const char *)datain + xindex + highy_int * ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLubyte)(*(temp_index)) * percent;
- }
- for(l = lowx_int+1; l < highx_int; l++) {
- temp += group_size;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLubyte)(*(temp_index)) * y_percent;
- }
- }
- temp += group_size;
- percent = y_percent * highx_float;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLubyte)(*(temp_index)) * percent;
- }
-
-
- /* calculate the value for pixels in the 1st and last column */
- for(m = lowy_int+1; m < highy_int; m++) {
- left += ysize;
- right += ysize;
- for (k = 0; k < components;
- k++, left += element_size, right += element_size) {
- totals[k] += (GLubyte)(*(left))*(1-lowx_float)
- +(GLubyte)(*(right))*highx_float;
- }
- }
- } else if (highy_int > lowy_int) {
- x_percent = highx_float - lowx_float;
- percent = (1-lowy_float)*x_percent;
- temp = (const char *)datain + xindex + lowy_int*ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLubyte)(*(temp_index)) * percent;
- }
- for(m = lowy_int+1; m < highy_int; m++) {
- temp += ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLubyte)(*(temp_index)) * x_percent;
- }
- }
- percent = x_percent * highy_float;
- temp += ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLubyte)(*(temp_index)) * percent;
- }
- } else if (highx_int > lowx_int) {
- y_percent = highy_float - lowy_float;
- percent = (1-lowx_float)*y_percent;
- temp = (const char *)datain + xindex + lowy_int*ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLubyte)(*(temp_index)) * percent;
- }
- for (l = lowx_int+1; l < highx_int; l++) {
- temp += group_size;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLubyte)(*(temp_index)) * y_percent;
- }
- }
- temp += group_size;
- percent = y_percent * highx_float;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLubyte)(*(temp_index)) * percent;
- }
- } else {
- percent = (highy_float-lowy_float)*(highx_float-lowx_float);
- temp = (const char *)datain + xindex + lowy_int * ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLubyte)(*(temp_index)) * percent;
- }
- }
-
-
-
- /* this is for the pixels in the body */
- temp0 = (const char *)datain + xindex + group_size +
- (lowy_int+1)*ysize;
- for (m = lowy_int+1; m < highy_int; m++) {
- temp = temp0;
- for(l = lowx_int+1; l < highx_int; l++) {
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLubyte)(*(temp_index));
- }
- temp += group_size;
- }
- temp0 += ysize;
- }
-
- outindex = (j + (i * widthout)) * components;
- for (k = 0; k < components; k++) {
- dataout[outindex + k] = totals[k]/area;
- /*printf("totals[%d] = %f\n", k, totals[k]);*/
- }
- lowx_int = highx_int;
- lowx_float = highx_float;
- highx_int += convx_int;
- highx_float += convx_float;
- if(highx_float > 1) {
- highx_float -= 1.0;
- highx_int++;
- }
- }
- lowy_int = highy_int;
- lowy_float = highy_float;
- highy_int += convy_int;
- highy_float += convy_float;
- if(highy_float > 1) {
- highy_float -= 1.0;
- highy_int++;
- }
- }
-}
-
-static void scale_internal_byte(GLint components, GLint widthin,
- GLint heightin, const GLbyte *datain,
- GLint widthout, GLint heightout,
- GLbyte *dataout, GLint element_size,
- GLint ysize, GLint group_size)
-{
- float convx;
- float convy;
- float percent;
- /* Max components in a format is 4, so... */
- float totals[4];
- float area;
- int i,j,k,xindex;
-
- const char *temp, *temp0;
- const char *temp_index;
- int outindex;
-
- int lowx_int, highx_int, lowy_int, highy_int;
- float x_percent, y_percent;
- float lowx_float, highx_float, lowy_float, highy_float;
- float convy_float, convx_float;
- int convy_int, convx_int;
- int l, m;
- const char *left, *right;
-
- if (widthin == widthout*2 && heightin == heightout*2) {
- halveImage_byte(components, widthin, heightin,
- (const GLbyte *)datain, (GLbyte *)dataout,
- element_size, ysize, group_size);
- return;
- }
- convy = (float) heightin/heightout;
- convx = (float) widthin/widthout;
- convy_int = floor(convy);
- convy_float = convy - convy_int;
- convx_int = floor(convx);
- convx_float = convx - convx_int;
-
- area = convx * convy;
-
- lowy_int = 0;
- lowy_float = 0;
- highy_int = convy_int;
- highy_float = convy_float;
-
- for (i = 0; i < heightout; i++) {
- /* Clamp here to be sure we don't read beyond input buffer. */
- if (highy_int >= heightin)
- highy_int = heightin - 1;
- lowx_int = 0;
- lowx_float = 0;
- highx_int = convx_int;
- highx_float = convx_float;
-
- for (j = 0; j < widthout; j++) {
-
- /*
- ** Ok, now apply box filter to box that goes from (lowx, lowy)
- ** to (highx, highy) on input data into this pixel on output
- ** data.
- */
- totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
-
- /* calculate the value for pixels in the 1st row */
- xindex = lowx_int*group_size;
- if((highy_int>lowy_int) && (highx_int>lowx_int)) {
-
- y_percent = 1-lowy_float;
- temp = (const char *)datain + xindex + lowy_int * ysize;
- percent = y_percent * (1-lowx_float);
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLbyte)(*(temp_index)) * percent;
- }
- left = temp;
- for(l = lowx_int+1; l < highx_int; l++) {
- temp += group_size;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLbyte)(*(temp_index)) * y_percent;
- }
- }
- temp += group_size;
- right = temp;
- percent = y_percent * highx_float;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLbyte)(*(temp_index)) * percent;
- }
-
- /* calculate the value for pixels in the last row */
- y_percent = highy_float;
- percent = y_percent * (1-lowx_float);
- temp = (const char *)datain + xindex + highy_int * ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLbyte)(*(temp_index)) * percent;
- }
- for(l = lowx_int+1; l < highx_int; l++) {
- temp += group_size;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLbyte)(*(temp_index)) * y_percent;
- }
- }
- temp += group_size;
- percent = y_percent * highx_float;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLbyte)(*(temp_index)) * percent;
- }
-
-
- /* calculate the value for pixels in the 1st and last column */
- for(m = lowy_int+1; m < highy_int; m++) {
- left += ysize;
- right += ysize;
- for (k = 0; k < components;
- k++, left += element_size, right += element_size) {
- totals[k] += (GLbyte)(*(left))*(1-lowx_float)
- +(GLbyte)(*(right))*highx_float;
- }
- }
- } else if (highy_int > lowy_int) {
- x_percent = highx_float - lowx_float;
- percent = (1-lowy_float)*x_percent;
- temp = (const char *)datain + xindex + lowy_int*ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLbyte)(*(temp_index)) * percent;
- }
- for(m = lowy_int+1; m < highy_int; m++) {
- temp += ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLbyte)(*(temp_index)) * x_percent;
- }
- }
- percent = x_percent * highy_float;
- temp += ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLbyte)(*(temp_index)) * percent;
- }
- } else if (highx_int > lowx_int) {
- y_percent = highy_float - lowy_float;
- percent = (1-lowx_float)*y_percent;
- temp = (const char *)datain + xindex + lowy_int*ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLbyte)(*(temp_index)) * percent;
- }
- for (l = lowx_int+1; l < highx_int; l++) {
- temp += group_size;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLbyte)(*(temp_index)) * y_percent;
- }
- }
- temp += group_size;
- percent = y_percent * highx_float;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLbyte)(*(temp_index)) * percent;
- }
- } else {
- percent = (highy_float-lowy_float)*(highx_float-lowx_float);
- temp = (const char *)datain + xindex + lowy_int * ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLbyte)(*(temp_index)) * percent;
- }
- }
-
-
-
- /* this is for the pixels in the body */
- temp0 = (const char *)datain + xindex + group_size +
- (lowy_int+1)*ysize;
- for (m = lowy_int+1; m < highy_int; m++) {
- temp = temp0;
- for(l = lowx_int+1; l < highx_int; l++) {
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- totals[k] += (GLbyte)(*(temp_index));
- }
- temp += group_size;
- }
- temp0 += ysize;
- }
-
- outindex = (j + (i * widthout)) * components;
- for (k = 0; k < components; k++) {
- dataout[outindex + k] = totals[k]/area;
- /*printf("totals[%d] = %f\n", k, totals[k]);*/
- }
- lowx_int = highx_int;
- lowx_float = highx_float;
- highx_int += convx_int;
- highx_float += convx_float;
- if(highx_float > 1) {
- highx_float -= 1.0;
- highx_int++;
- }
- }
- lowy_int = highy_int;
- lowy_float = highy_float;
- highy_int += convy_int;
- highy_float += convy_float;
- if(highy_float > 1) {
- highy_float -= 1.0;
- highy_int++;
- }
- }
-}
-
-static void scale_internal_ushort(GLint components, GLint widthin,
- GLint heightin, const GLushort *datain,
- GLint widthout, GLint heightout,
- GLushort *dataout, GLint element_size,
- GLint ysize, GLint group_size,
- GLint myswap_bytes)
-{
- float convx;
- float convy;
- float percent;
- /* Max components in a format is 4, so... */
- float totals[4];
- float area;
- int i,j,k,xindex;
-
- const char *temp, *temp0;
- const char *temp_index;
- int outindex;
-
- int lowx_int, highx_int, lowy_int, highy_int;
- float x_percent, y_percent;
- float lowx_float, highx_float, lowy_float, highy_float;
- float convy_float, convx_float;
- int convy_int, convx_int;
- int l, m;
- const char *left, *right;
-
- if (widthin == widthout*2 && heightin == heightout*2) {
- halveImage_ushort(components, widthin, heightin,
- (const GLushort *)datain, (GLushort *)dataout,
- element_size, ysize, group_size, myswap_bytes);
- return;
- }
- convy = (float) heightin/heightout;
- convx = (float) widthin/widthout;
- convy_int = floor(convy);
- convy_float = convy - convy_int;
- convx_int = floor(convx);
- convx_float = convx - convx_int;
-
- area = convx * convy;
-
- lowy_int = 0;
- lowy_float = 0;
- highy_int = convy_int;
- highy_float = convy_float;
-
- for (i = 0; i < heightout; i++) {
- /* Clamp here to be sure we don't read beyond input buffer. */
- if (highy_int >= heightin)
- highy_int = heightin - 1;
- lowx_int = 0;
- lowx_float = 0;
- highx_int = convx_int;
- highx_float = convx_float;
-
- for (j = 0; j < widthout; j++) {
- /*
- ** Ok, now apply box filter to box that goes from (lowx, lowy)
- ** to (highx, highy) on input data into this pixel on output
- ** data.
- */
- totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
-
- /* calculate the value for pixels in the 1st row */
- xindex = lowx_int*group_size;
- if((highy_int>lowy_int) && (highx_int>lowx_int)) {
-
- y_percent = 1-lowy_float;
- temp = (const char *)datain + xindex + lowy_int * ysize;
- percent = y_percent * (1-lowx_float);
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * percent;
- }
- }
- left = temp;
- for(l = lowx_int+1; l < highx_int; l++) {
- temp += group_size;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] +=
- __GLU_SWAP_2_BYTES(temp_index) * y_percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * y_percent;
- }
- }
- }
- temp += group_size;
- right = temp;
- percent = y_percent * highx_float;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * percent;
- }
- }
-
- /* calculate the value for pixels in the last row */
- y_percent = highy_float;
- percent = y_percent * (1-lowx_float);
- temp = (const char *)datain + xindex + highy_int * ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * percent;
- }
- }
- for(l = lowx_int+1; l < highx_int; l++) {
- temp += group_size;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] +=
- __GLU_SWAP_2_BYTES(temp_index) * y_percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * y_percent;
- }
- }
- }
- temp += group_size;
- percent = y_percent * highx_float;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * percent;
- }
- }
-
- /* calculate the value for pixels in the 1st and last column */
- for(m = lowy_int+1; m < highy_int; m++) {
- left += ysize;
- right += ysize;
- for (k = 0; k < components;
- k++, left += element_size, right += element_size) {
- if (myswap_bytes) {
- totals[k] +=
- __GLU_SWAP_2_BYTES(left) * (1-lowx_float) +
- __GLU_SWAP_2_BYTES(right) * highx_float;
- } else {
- totals[k] += *(const GLushort*)left * (1-lowx_float)
- + *(const GLushort*)right * highx_float;
- }
- }
- }
- } else if (highy_int > lowy_int) {
- x_percent = highx_float - lowx_float;
- percent = (1-lowy_float)*x_percent;
- temp = (const char *)datain + xindex + lowy_int*ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * percent;
- }
- }
- for(m = lowy_int+1; m < highy_int; m++) {
- temp += ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] +=
- __GLU_SWAP_2_BYTES(temp_index) * x_percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * x_percent;
- }
- }
- }
- percent = x_percent * highy_float;
- temp += ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * percent;
- }
- }
- } else if (highx_int > lowx_int) {
- y_percent = highy_float - lowy_float;
- percent = (1-lowx_float)*y_percent;
- temp = (const char *)datain + xindex + lowy_int*ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * percent;
- }
- }
- for (l = lowx_int+1; l < highx_int; l++) {
- temp += group_size;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] +=
- __GLU_SWAP_2_BYTES(temp_index) * y_percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * y_percent;
- }
- }
- }
- temp += group_size;
- percent = y_percent * highx_float;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * percent;
- }
- }
- } else {
- percent = (highy_float-lowy_float)*(highx_float-lowx_float);
- temp = (const char *)datain + xindex + lowy_int * ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * percent;
- }
- }
- }
-
- /* this is for the pixels in the body */
- temp0 = (const char *)datain + xindex + group_size +
- (lowy_int+1)*ysize;
- for (m = lowy_int+1; m < highy_int; m++) {
- temp = temp0;
- for(l = lowx_int+1; l < highx_int; l++) {
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_2_BYTES(temp_index);
- } else {
- totals[k] += *(const GLushort*)temp_index;
- }
- }
- temp += group_size;
- }
- temp0 += ysize;
- }
-
- outindex = (j + (i * widthout)) * components;
- for (k = 0; k < components; k++) {
- dataout[outindex + k] = totals[k]/area;
- /*printf("totals[%d] = %f\n", k, totals[k]);*/
- }
- lowx_int = highx_int;
- lowx_float = highx_float;
- highx_int += convx_int;
- highx_float += convx_float;
- if(highx_float > 1) {
- highx_float -= 1.0;
- highx_int++;
- }
- }
- lowy_int = highy_int;
- lowy_float = highy_float;
- highy_int += convy_int;
- highy_float += convy_float;
- if(highy_float > 1) {
- highy_float -= 1.0;
- highy_int++;
- }
- }
-}
-
-static void scale_internal_short(GLint components, GLint widthin,
- GLint heightin, const GLshort *datain,
- GLint widthout, GLint heightout,
- GLshort *dataout, GLint element_size,
- GLint ysize, GLint group_size,
- GLint myswap_bytes)
-{
- float convx;
- float convy;
- float percent;
- /* Max components in a format is 4, so... */
- float totals[4];
- float area;
- int i,j,k,xindex;
-
- const char *temp, *temp0;
- const char *temp_index;
- int outindex;
-
- int lowx_int, highx_int, lowy_int, highy_int;
- float x_percent, y_percent;
- float lowx_float, highx_float, lowy_float, highy_float;
- float convy_float, convx_float;
- int convy_int, convx_int;
- int l, m;
- const char *left, *right;
-
- GLushort swapbuf; /* unsigned buffer */
-
- if (widthin == widthout*2 && heightin == heightout*2) {
- halveImage_short(components, widthin, heightin,
- (const GLshort *)datain, (GLshort *)dataout,
- element_size, ysize, group_size, myswap_bytes);
- return;
- }
- convy = (float) heightin/heightout;
- convx = (float) widthin/widthout;
- convy_int = floor(convy);
- convy_float = convy - convy_int;
- convx_int = floor(convx);
- convx_float = convx - convx_int;
-
- area = convx * convy;
-
- lowy_int = 0;
- lowy_float = 0;
- highy_int = convy_int;
- highy_float = convy_float;
-
- for (i = 0; i < heightout; i++) {
- /* Clamp here to be sure we don't read beyond input buffer. */
- if (highy_int >= heightin)
- highy_int = heightin - 1;
- lowx_int = 0;
- lowx_float = 0;
- highx_int = convx_int;
- highx_float = convx_float;
-
- for (j = 0; j < widthout; j++) {
- /*
- ** Ok, now apply box filter to box that goes from (lowx, lowy)
- ** to (highx, highy) on input data into this pixel on output
- ** data.
- */
- totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
-
- /* calculate the value for pixels in the 1st row */
- xindex = lowx_int*group_size;
- if((highy_int>lowy_int) && (highx_int>lowx_int)) {
-
- y_percent = 1-lowy_float;
- temp = (const char *)datain + xindex + lowy_int * ysize;
- percent = y_percent * (1-lowx_float);
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_2_BYTES(temp_index);
- totals[k] += *(const GLshort*)&swapbuf * percent;
- } else {
- totals[k] += *(const GLshort*)temp_index * percent;
- }
- }
- left = temp;
- for(l = lowx_int+1; l < highx_int; l++) {
- temp += group_size;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_2_BYTES(temp_index);
- totals[k] += *(const GLshort*)&swapbuf * y_percent;
- } else {
- totals[k] += *(const GLshort*)temp_index * y_percent;
- }
- }
- }
- temp += group_size;
- right = temp;
- percent = y_percent * highx_float;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_2_BYTES(temp_index);
- totals[k] += *(const GLshort*)&swapbuf * percent;
- } else {
- totals[k] += *(const GLshort*)temp_index * percent;
- }
- }
-
- /* calculate the value for pixels in the last row */
- y_percent = highy_float;
- percent = y_percent * (1-lowx_float);
- temp = (const char *)datain + xindex + highy_int * ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_2_BYTES(temp_index);
- totals[k] += *(const GLshort*)&swapbuf * percent;
- } else {
- totals[k] += *(const GLshort*)temp_index * percent;
- }
- }
- for(l = lowx_int+1; l < highx_int; l++) {
- temp += group_size;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_2_BYTES(temp_index);
- totals[k] += *(const GLshort*)&swapbuf * y_percent;
- } else {
- totals[k] += *(const GLshort*)temp_index * y_percent;
- }
- }
- }
- temp += group_size;
- percent = y_percent * highx_float;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_2_BYTES(temp_index);
- totals[k] += *(const GLshort*)&swapbuf * percent;
- } else {
- totals[k] += *(const GLshort*)temp_index * percent;
- }
- }
-
- /* calculate the value for pixels in the 1st and last column */
- for(m = lowy_int+1; m < highy_int; m++) {
- left += ysize;
- right += ysize;
- for (k = 0; k < components;
- k++, left += element_size, right += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_2_BYTES(left);
- totals[k] += *(const GLshort*)&swapbuf * (1-lowx_float);
- swapbuf = __GLU_SWAP_2_BYTES(right);
- totals[k] += *(const GLshort*)&swapbuf * highx_float;
- } else {
- totals[k] += *(const GLshort*)left * (1-lowx_float)
- + *(const GLshort*)right * highx_float;
- }
- }
- }
- } else if (highy_int > lowy_int) {
- x_percent = highx_float - lowx_float;
- percent = (1-lowy_float)*x_percent;
- temp = (const char *)datain + xindex + lowy_int*ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_2_BYTES(temp_index);
- totals[k] += *(const GLshort*)&swapbuf * percent;
- } else {
- totals[k] += *(const GLshort*)temp_index * percent;
- }
- }
- for(m = lowy_int+1; m < highy_int; m++) {
- temp += ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_2_BYTES(temp_index);
- totals[k] += *(const GLshort*)&swapbuf * x_percent;
- } else {
- totals[k] += *(const GLshort*)temp_index * x_percent;
- }
- }
- }
- percent = x_percent * highy_float;
- temp += ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_2_BYTES(temp_index);
- totals[k] += *(const GLshort*)&swapbuf * percent;
- } else {
- totals[k] += *(const GLshort*)temp_index * percent;
- }
- }
- } else if (highx_int > lowx_int) {
- y_percent = highy_float - lowy_float;
- percent = (1-lowx_float)*y_percent;
-
- temp = (const char *)datain + xindex + lowy_int*ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_2_BYTES(temp_index);
- totals[k] += *(const GLshort*)&swapbuf * percent;
- } else {
- totals[k] += *(const GLshort*)temp_index * percent;
- }
- }
- for (l = lowx_int+1; l < highx_int; l++) {
- temp += group_size;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_2_BYTES(temp_index);
- totals[k] += *(const GLshort*)&swapbuf * y_percent;
- } else {
- totals[k] += *(const GLshort*)temp_index * y_percent;
- }
- }
- }
- temp += group_size;
- percent = y_percent * highx_float;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_2_BYTES(temp_index);
- totals[k] += *(const GLshort*)&swapbuf * percent;
- } else {
- totals[k] += *(const GLshort*)temp_index * percent;
- }
- }
- } else {
- percent = (highy_float-lowy_float)*(highx_float-lowx_float);
- temp = (const char *)datain + xindex + lowy_int * ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_2_BYTES(temp_index);
- totals[k] += *(const GLshort*)&swapbuf * percent;
- } else {
- totals[k] += *(const GLshort*)temp_index * percent;
- }
- }
- }
-
- /* this is for the pixels in the body */
- temp0 = (const char *)datain + xindex + group_size +
- (lowy_int+1)*ysize;
- for (m = lowy_int+1; m < highy_int; m++) {
- temp = temp0;
- for(l = lowx_int+1; l < highx_int; l++) {
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_2_BYTES(temp_index);
- totals[k] += *(const GLshort*)&swapbuf;
- } else {
- totals[k] += *(const GLshort*)temp_index;
- }
- }
- temp += group_size;
- }
- temp0 += ysize;
- }
-
- outindex = (j + (i * widthout)) * components;
- for (k = 0; k < components; k++) {
- dataout[outindex + k] = totals[k]/area;
- /*printf("totals[%d] = %f\n", k, totals[k]);*/
- }
- lowx_int = highx_int;
- lowx_float = highx_float;
- highx_int += convx_int;
- highx_float += convx_float;
- if(highx_float > 1) {
- highx_float -= 1.0;
- highx_int++;
- }
- }
- lowy_int = highy_int;
- lowy_float = highy_float;
- highy_int += convy_int;
- highy_float += convy_float;
- if(highy_float > 1) {
- highy_float -= 1.0;
- highy_int++;
- }
- }
-}
-
-static void scale_internal_uint(GLint components, GLint widthin,
- GLint heightin, const GLuint *datain,
- GLint widthout, GLint heightout,
- GLuint *dataout, GLint element_size,
- GLint ysize, GLint group_size,
- GLint myswap_bytes)
-{
- float convx;
- float convy;
- float percent;
- /* Max components in a format is 4, so... */
- float totals[4];
- float area;
- int i,j,k,xindex;
-
- const char *temp, *temp0;
- const char *temp_index;
- int outindex;
-
- int lowx_int, highx_int, lowy_int, highy_int;
- float x_percent, y_percent;
- float lowx_float, highx_float, lowy_float, highy_float;
- float convy_float, convx_float;
- int convy_int, convx_int;
- int l, m;
- const char *left, *right;
-
- if (widthin == widthout*2 && heightin == heightout*2) {
- halveImage_uint(components, widthin, heightin,
- (const GLuint *)datain, (GLuint *)dataout,
- element_size, ysize, group_size, myswap_bytes);
- return;
- }
- convy = (float) heightin/heightout;
- convx = (float) widthin/widthout;
- convy_int = floor(convy);
- convy_float = convy - convy_int;
- convx_int = floor(convx);
- convx_float = convx - convx_int;
-
- area = convx * convy;
-
- lowy_int = 0;
- lowy_float = 0;
- highy_int = convy_int;
- highy_float = convy_float;
-
- for (i = 0; i < heightout; i++) {
- /* Clamp here to be sure we don't read beyond input buffer. */
- if (highy_int >= heightin)
- highy_int = heightin - 1;
- lowx_int = 0;
- lowx_float = 0;
- highx_int = convx_int;
- highx_float = convx_float;
-
- for (j = 0; j < widthout; j++) {
- /*
- ** Ok, now apply box filter to box that goes from (lowx, lowy)
- ** to (highx, highy) on input data into this pixel on output
- ** data.
- */
- totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
-
- /* calculate the value for pixels in the 1st row */
- xindex = lowx_int*group_size;
- if((highy_int>lowy_int) && (highx_int>lowx_int)) {
-
- y_percent = 1-lowy_float;
- temp = (const char *)datain + xindex + lowy_int * ysize;
- percent = y_percent * (1-lowx_float);
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLuint*)temp_index * percent;
- }
- }
- left = temp;
- for(l = lowx_int+1; l < highx_int; l++) {
- temp += group_size;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] +=
- __GLU_SWAP_4_BYTES(temp_index) * y_percent;
- } else {
- totals[k] += *(const GLuint*)temp_index * y_percent;
- }
- }
- }
- temp += group_size;
- right = temp;
- percent = y_percent * highx_float;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLuint*)temp_index * percent;
- }
- }
-
- /* calculate the value for pixels in the last row */
- y_percent = highy_float;
- percent = y_percent * (1-lowx_float);
- temp = (const char *)datain + xindex + highy_int * ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLuint*)temp_index * percent;
- }
- }
- for(l = lowx_int+1; l < highx_int; l++) {
- temp += group_size;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] +=
- __GLU_SWAP_4_BYTES(temp_index) * y_percent;
- } else {
- totals[k] += *(const GLuint*)temp_index * y_percent;
- }
- }
- }
- temp += group_size;
- percent = y_percent * highx_float;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLuint*)temp_index * percent;
- }
- }
-
- /* calculate the value for pixels in the 1st and last column */
- for(m = lowy_int+1; m < highy_int; m++) {
- left += ysize;
- right += ysize;
- for (k = 0; k < components;
- k++, left += element_size, right += element_size) {
- if (myswap_bytes) {
- totals[k] +=
- __GLU_SWAP_4_BYTES(left) * (1-lowx_float)
- + __GLU_SWAP_4_BYTES(right) * highx_float;
- } else {
- totals[k] += *(const GLuint*)left * (1-lowx_float)
- + *(const GLuint*)right * highx_float;
- }
- }
- }
- } else if (highy_int > lowy_int) {
- x_percent = highx_float - lowx_float;
- percent = (1-lowy_float)*x_percent;
- temp = (const char *)datain + xindex + lowy_int*ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLuint*)temp_index * percent;
- }
- }
- for(m = lowy_int+1; m < highy_int; m++) {
- temp += ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] +=
- __GLU_SWAP_4_BYTES(temp_index) * x_percent;
- } else {
- totals[k] += *(const GLuint*)temp_index * x_percent;
- }
- }
- }
- percent = x_percent * highy_float;
- temp += ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLuint*)temp_index * percent;
- }
- }
- } else if (highx_int > lowx_int) {
- y_percent = highy_float - lowy_float;
- percent = (1-lowx_float)*y_percent;
-
- temp = (const char *)datain + xindex + lowy_int*ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLuint*)temp_index * percent;
- }
- }
- for (l = lowx_int+1; l < highx_int; l++) {
- temp += group_size;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] +=
- __GLU_SWAP_4_BYTES(temp_index) * y_percent;
- } else {
- totals[k] += *(const GLuint*)temp_index * y_percent;
- }
- }
- }
- temp += group_size;
- percent = y_percent * highx_float;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLuint*)temp_index * percent;
- }
- }
- } else {
- percent = (highy_float-lowy_float)*(highx_float-lowx_float);
- temp = (const char *)datain + xindex + lowy_int * ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLuint*)temp_index * percent;
- }
- }
- }
-
- /* this is for the pixels in the body */
- temp0 = (const char *)datain + xindex + group_size +
- (lowy_int+1)*ysize;
- for (m = lowy_int+1; m < highy_int; m++) {
- temp = temp0;
- for(l = lowx_int+1; l < highx_int; l++) {
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_4_BYTES(temp_index);
- } else {
- totals[k] += *(const GLuint*)temp_index;
- }
- }
- temp += group_size;
- }
- temp0 += ysize;
- }
-
- outindex = (j + (i * widthout)) * components;
- for (k = 0; k < components; k++) {
- /* clamp at UINT_MAX */
- float value= totals[k]/area;
- if (value >= (float) UINT_MAX) { /* need '=' */
- dataout[outindex + k] = UINT_MAX;
- }
- else dataout[outindex + k] = value;
- }
- lowx_int = highx_int;
- lowx_float = highx_float;
- highx_int += convx_int;
- highx_float += convx_float;
- if(highx_float > 1) {
- highx_float -= 1.0;
- highx_int++;
- }
- }
- lowy_int = highy_int;
- lowy_float = highy_float;
- highy_int += convy_int;
- highy_float += convy_float;
- if(highy_float > 1) {
- highy_float -= 1.0;
- highy_int++;
- }
- }
-}
-
-
-
-static void scale_internal_int(GLint components, GLint widthin,
- GLint heightin, const GLint *datain,
- GLint widthout, GLint heightout,
- GLint *dataout, GLint element_size,
- GLint ysize, GLint group_size,
- GLint myswap_bytes)
-{
- float convx;
- float convy;
- float percent;
- /* Max components in a format is 4, so... */
- float totals[4];
- float area;
- int i,j,k,xindex;
-
- const char *temp, *temp0;
- const char *temp_index;
- int outindex;
-
- int lowx_int, highx_int, lowy_int, highy_int;
- float x_percent, y_percent;
- float lowx_float, highx_float, lowy_float, highy_float;
- float convy_float, convx_float;
- int convy_int, convx_int;
- int l, m;
- const char *left, *right;
-
- GLuint swapbuf; /* unsigned buffer */
-
- if (widthin == widthout*2 && heightin == heightout*2) {
- halveImage_int(components, widthin, heightin,
- (const GLint *)datain, (GLint *)dataout,
- element_size, ysize, group_size, myswap_bytes);
- return;
- }
- convy = (float) heightin/heightout;
- convx = (float) widthin/widthout;
- convy_int = floor(convy);
- convy_float = convy - convy_int;
- convx_int = floor(convx);
- convx_float = convx - convx_int;
-
- area = convx * convy;
-
- lowy_int = 0;
- lowy_float = 0;
- highy_int = convy_int;
- highy_float = convy_float;
-
- for (i = 0; i < heightout; i++) {
- /* Clamp here to be sure we don't read beyond input buffer. */
- if (highy_int >= heightin)
- highy_int = heightin - 1;
- lowx_int = 0;
- lowx_float = 0;
- highx_int = convx_int;
- highx_float = convx_float;
-
- for (j = 0; j < widthout; j++) {
- /*
- ** Ok, now apply box filter to box that goes from (lowx, lowy)
- ** to (highx, highy) on input data into this pixel on output
- ** data.
- */
- totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
-
- /* calculate the value for pixels in the 1st row */
- xindex = lowx_int*group_size;
- if((highy_int>lowy_int) && (highx_int>lowx_int)) {
-
- y_percent = 1-lowy_float;
- temp = (const char *)datain + xindex + lowy_int * ysize;
- percent = y_percent * (1-lowx_float);
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += *(const GLint*)&swapbuf * percent;
- } else {
- totals[k] += *(const GLint*)temp_index * percent;
- }
- }
- left = temp;
- for(l = lowx_int+1; l < highx_int; l++) {
- temp += group_size;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += *(const GLint*)&swapbuf * y_percent;
- } else {
- totals[k] += *(const GLint*)temp_index * y_percent;
- }
- }
- }
- temp += group_size;
- right = temp;
- percent = y_percent * highx_float;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += *(const GLint*)&swapbuf * percent;
- } else {
- totals[k] += *(const GLint*)temp_index * percent;
- }
- }
-
- /* calculate the value for pixels in the last row */
- y_percent = highy_float;
- percent = y_percent * (1-lowx_float);
- temp = (const char *)datain + xindex + highy_int * ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += *(const GLint*)&swapbuf * percent;
- } else {
- totals[k] += *(const GLint*)temp_index * percent;
- }
- }
- for(l = lowx_int+1; l < highx_int; l++) {
- temp += group_size;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += *(const GLint*)&swapbuf * y_percent;
- } else {
- totals[k] += *(const GLint*)temp_index * y_percent;
- }
- }
- }
- temp += group_size;
- percent = y_percent * highx_float;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += *(const GLint*)&swapbuf * percent;
- } else {
- totals[k] += *(const GLint*)temp_index * percent;
- }
- }
-
- /* calculate the value for pixels in the 1st and last column */
- for(m = lowy_int+1; m < highy_int; m++) {
- left += ysize;
- right += ysize;
- for (k = 0; k < components;
- k++, left += element_size, right += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_4_BYTES(left);
- totals[k] += *(const GLint*)&swapbuf * (1-lowx_float);
- swapbuf = __GLU_SWAP_4_BYTES(right);
- totals[k] += *(const GLint*)&swapbuf * highx_float;
- } else {
- totals[k] += *(const GLint*)left * (1-lowx_float)
- + *(const GLint*)right * highx_float;
- }
- }
- }
- } else if (highy_int > lowy_int) {
- x_percent = highx_float - lowx_float;
- percent = (1-lowy_float)*x_percent;
- temp = (const char *)datain + xindex + lowy_int*ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += *(const GLint*)&swapbuf * percent;
- } else {
- totals[k] += *(const GLint*)temp_index * percent;
- }
- }
- for(m = lowy_int+1; m < highy_int; m++) {
- temp += ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += *(const GLint*)&swapbuf * x_percent;
- } else {
- totals[k] += *(const GLint*)temp_index * x_percent;
- }
- }
- }
- percent = x_percent * highy_float;
- temp += ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += *(const GLint*)&swapbuf * percent;
- } else {
- totals[k] += *(const GLint*)temp_index * percent;
- }
- }
- } else if (highx_int > lowx_int) {
- y_percent = highy_float - lowy_float;
- percent = (1-lowx_float)*y_percent;
-
- temp = (const char *)datain + xindex + lowy_int*ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += *(const GLint*)&swapbuf * percent;
- } else {
- totals[k] += *(const GLint*)temp_index * percent;
- }
- }
- for (l = lowx_int+1; l < highx_int; l++) {
- temp += group_size;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += *(const GLint*)&swapbuf * y_percent;
- } else {
- totals[k] += *(const GLint*)temp_index * y_percent;
- }
- }
- }
- temp += group_size;
- percent = y_percent * highx_float;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += *(const GLint*)&swapbuf * percent;
- } else {
- totals[k] += *(const GLint*)temp_index * percent;
- }
- }
- } else {
- percent = (highy_float-lowy_float)*(highx_float-lowx_float);
- temp = (const char *)datain + xindex + lowy_int * ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += *(const GLint*)&swapbuf * percent;
- } else {
- totals[k] += *(const GLint*)temp_index * percent;
- }
- }
- }
-
- /* this is for the pixels in the body */
- temp0 = (const char *)datain + xindex + group_size +
- (lowy_int+1)*ysize;
- for (m = lowy_int+1; m < highy_int; m++) {
- temp = temp0;
- for(l = lowx_int+1; l < highx_int; l++) {
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += *(const GLint*)&swapbuf;
- } else {
- totals[k] += *(const GLint*)temp_index;
- }
- }
- temp += group_size;
- }
- temp0 += ysize;
- }
-
- outindex = (j + (i * widthout)) * components;
- for (k = 0; k < components; k++) {
- dataout[outindex + k] = totals[k]/area;
- /*printf("totals[%d] = %f\n", k, totals[k]);*/
- }
- lowx_int = highx_int;
- lowx_float = highx_float;
- highx_int += convx_int;
- highx_float += convx_float;
- if(highx_float > 1) {
- highx_float -= 1.0;
- highx_int++;
- }
- }
- lowy_int = highy_int;
- lowy_float = highy_float;
- highy_int += convy_int;
- highy_float += convy_float;
- if(highy_float > 1) {
- highy_float -= 1.0;
- highy_int++;
- }
- }
-}
-
-
-
-static void scale_internal_float(GLint components, GLint widthin,
- GLint heightin, const GLfloat *datain,
- GLint widthout, GLint heightout,
- GLfloat *dataout, GLint element_size,
- GLint ysize, GLint group_size,
- GLint myswap_bytes)
-{
- float convx;
- float convy;
- float percent;
- /* Max components in a format is 4, so... */
- float totals[4];
- float area;
- int i,j,k,xindex;
-
- const char *temp, *temp0;
- const char *temp_index;
- int outindex;
-
- int lowx_int, highx_int, lowy_int, highy_int;
- float x_percent, y_percent;
- float lowx_float, highx_float, lowy_float, highy_float;
- float convy_float, convx_float;
- int convy_int, convx_int;
- int l, m;
- const char *left, *right;
-
- union { GLuint b; GLfloat f; } swapbuf;
-
- if (widthin == widthout*2 && heightin == heightout*2) {
- halveImage_float(components, widthin, heightin,
- (const GLfloat *)datain, (GLfloat *)dataout,
- element_size, ysize, group_size, myswap_bytes);
- return;
- }
- convy = (float) heightin/heightout;
- convx = (float) widthin/widthout;
- convy_int = floor(convy);
- convy_float = convy - convy_int;
- convx_int = floor(convx);
- convx_float = convx - convx_int;
-
- area = convx * convy;
-
- lowy_int = 0;
- lowy_float = 0;
- highy_int = convy_int;
- highy_float = convy_float;
-
- for (i = 0; i < heightout; i++) {
- /* Clamp here to be sure we don't read beyond input buffer. */
- if (highy_int >= heightin)
- highy_int = heightin - 1;
- lowx_int = 0;
- lowx_float = 0;
- highx_int = convx_int;
- highx_float = convx_float;
-
- for (j = 0; j < widthout; j++) {
- /*
- ** Ok, now apply box filter to box that goes from (lowx, lowy)
- ** to (highx, highy) on input data into this pixel on output
- ** data.
- */
- totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
-
- /* calculate the value for pixels in the 1st row */
- xindex = lowx_int*group_size;
- if((highy_int>lowy_int) && (highx_int>lowx_int)) {
-
- y_percent = 1-lowy_float;
- temp = (const char *)datain + xindex + lowy_int * ysize;
- percent = y_percent * (1-lowx_float);
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += swapbuf.f * percent;
- } else {
- totals[k] += *(const GLfloat*)temp_index * percent;
- }
- }
- left = temp;
- for(l = lowx_int+1; l < highx_int; l++) {
- temp += group_size;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += swapbuf.f * y_percent;
- } else {
- totals[k] += *(const GLfloat*)temp_index * y_percent;
- }
- }
- }
- temp += group_size;
- right = temp;
- percent = y_percent * highx_float;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += swapbuf.f * percent;
- } else {
- totals[k] += *(const GLfloat*)temp_index * percent;
- }
- }
-
- /* calculate the value for pixels in the last row */
- y_percent = highy_float;
- percent = y_percent * (1-lowx_float);
- temp = (const char *)datain + xindex + highy_int * ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += swapbuf.f * percent;
- } else {
- totals[k] += *(const GLfloat*)temp_index * percent;
- }
- }
- for(l = lowx_int+1; l < highx_int; l++) {
- temp += group_size;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += swapbuf.f * y_percent;
- } else {
- totals[k] += *(const GLfloat*)temp_index * y_percent;
- }
- }
- }
- temp += group_size;
- percent = y_percent * highx_float;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += swapbuf.f * percent;
- } else {
- totals[k] += *(const GLfloat*)temp_index * percent;
- }
- }
-
- /* calculate the value for pixels in the 1st and last column */
- for(m = lowy_int+1; m < highy_int; m++) {
- left += ysize;
- right += ysize;
- for (k = 0; k < components;
- k++, left += element_size, right += element_size) {
- if (myswap_bytes) {
- swapbuf.b = __GLU_SWAP_4_BYTES(left);
- totals[k] += swapbuf.f * (1-lowx_float);
- swapbuf.b = __GLU_SWAP_4_BYTES(right);
- totals[k] += swapbuf.f * highx_float;
- } else {
- totals[k] += *(const GLfloat*)left * (1-lowx_float)
- + *(const GLfloat*)right * highx_float;
- }
- }
- }
- } else if (highy_int > lowy_int) {
- x_percent = highx_float - lowx_float;
- percent = (1-lowy_float)*x_percent;
- temp = (const char *)datain + xindex + lowy_int*ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += swapbuf.f * percent;
- } else {
- totals[k] += *(const GLfloat*)temp_index * percent;
- }
- }
- for(m = lowy_int+1; m < highy_int; m++) {
- temp += ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += swapbuf.f * x_percent;
- } else {
- totals[k] += *(const GLfloat*)temp_index * x_percent;
- }
- }
- }
- percent = x_percent * highy_float;
- temp += ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += swapbuf.f * percent;
- } else {
- totals[k] += *(const GLfloat*)temp_index * percent;
- }
- }
- } else if (highx_int > lowx_int) {
- y_percent = highy_float - lowy_float;
- percent = (1-lowx_float)*y_percent;
-
- temp = (const char *)datain + xindex + lowy_int*ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += swapbuf.f * percent;
- } else {
- totals[k] += *(const GLfloat*)temp_index * percent;
- }
- }
- for (l = lowx_int+1; l < highx_int; l++) {
- temp += group_size;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += swapbuf.f * y_percent;
- } else {
- totals[k] += *(const GLfloat*)temp_index * y_percent;
- }
- }
- }
- temp += group_size;
- percent = y_percent * highx_float;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += swapbuf.f * percent;
- } else {
- totals[k] += *(const GLfloat*)temp_index * percent;
- }
- }
- } else {
- percent = (highy_float-lowy_float)*(highx_float-lowx_float);
- temp = (const char *)datain + xindex + lowy_int * ysize;
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += swapbuf.f * percent;
- } else {
- totals[k] += *(const GLfloat*)temp_index * percent;
- }
- }
- }
-
- /* this is for the pixels in the body */
- temp0 = (const char *)datain + xindex + group_size +
- (lowy_int+1)*ysize;
- for (m = lowy_int+1; m < highy_int; m++) {
- temp = temp0;
- for(l = lowx_int+1; l < highx_int; l++) {
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- swapbuf.b = __GLU_SWAP_4_BYTES(temp_index);
- totals[k] += swapbuf.f;
- } else {
- totals[k] += *(const GLfloat*)temp_index;
- }
- }
- temp += group_size;
- }
- temp0 += ysize;
- }
-
- outindex = (j + (i * widthout)) * components;
- for (k = 0; k < components; k++) {
- dataout[outindex + k] = totals[k]/area;
- /*printf("totals[%d] = %f\n", k, totals[k]);*/
- }
- lowx_int = highx_int;
- lowx_float = highx_float;
- highx_int += convx_int;
- highx_float += convx_float;
- if(highx_float > 1) {
- highx_float -= 1.0;
- highx_int++;
- }
- }
- lowy_int = highy_int;
- lowy_float = highy_float;
- highy_int += convy_int;
- highy_float += convy_float;
- if(highy_float > 1) {
- highy_float -= 1.0;
- highy_int++;
- }
- }
-}
-
-static int checkMipmapArgs(GLenum internalFormat, GLenum format, GLenum type)
-{
- if (!legalFormat(format) || !legalType(type)) {
- return GLU_INVALID_ENUM;
- }
- if (format == GL_STENCIL_INDEX) {
- return GLU_INVALID_ENUM;
- }
-
- if (!isLegalFormatForPackedPixelType(format, type)) {
- return GLU_INVALID_OPERATION;
- }
-
- return 0;
-} /* checkMipmapArgs() */
-
-static GLboolean legalFormat(GLenum format)
-{
- switch(format) {
- case GL_COLOR_INDEX:
- case GL_STENCIL_INDEX:
- case GL_DEPTH_COMPONENT:
- case GL_RED:
- case GL_GREEN:
- case GL_BLUE:
- case GL_ALPHA:
- case GL_RGB:
- case GL_RGBA:
- case GL_LUMINANCE:
- case GL_LUMINANCE_ALPHA:
- case GL_BGR:
- case GL_BGRA:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-static GLboolean legalType(GLenum type)
-{
- switch(type) {
- case GL_BITMAP:
- case GL_BYTE:
- case GL_UNSIGNED_BYTE:
- case GL_SHORT:
- case GL_UNSIGNED_SHORT:
- case GL_INT:
- case GL_UNSIGNED_INT:
- case GL_FLOAT:
- case GL_UNSIGNED_BYTE_3_3_2:
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- case GL_UNSIGNED_INT_8_8_8_8:
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- case GL_UNSIGNED_INT_10_10_10_2:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-/* */
-static GLboolean isTypePackedPixel(GLenum type)
-{
- assert(legalType(type));
-
- if (type == GL_UNSIGNED_BYTE_3_3_2 ||
- type == GL_UNSIGNED_BYTE_2_3_3_REV ||
- type == GL_UNSIGNED_SHORT_5_6_5 ||
- type == GL_UNSIGNED_SHORT_5_6_5_REV ||
- type == GL_UNSIGNED_SHORT_4_4_4_4 ||
- type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
- type == GL_UNSIGNED_SHORT_5_5_5_1 ||
- type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
- type == GL_UNSIGNED_INT_8_8_8_8 ||
- type == GL_UNSIGNED_INT_8_8_8_8_REV ||
- type == GL_UNSIGNED_INT_10_10_10_2 ||
- type == GL_UNSIGNED_INT_2_10_10_10_REV) {
- return 1;
- }
- else return 0;
-} /* isTypePackedPixel() */
-
-/* Determines if the packed pixel type is compatible with the format */
-static GLboolean isLegalFormatForPackedPixelType(GLenum format, GLenum type)
-{
- /* if not a packed pixel type then return true */
- if (!isTypePackedPixel(type)) {
- return GL_TRUE;
- }
-
- /* 3_3_2/2_3_3_REV & 5_6_5/5_6_5_REV are only compatible with RGB */
- if ((type == GL_UNSIGNED_BYTE_3_3_2 || type == GL_UNSIGNED_BYTE_2_3_3_REV||
- type == GL_UNSIGNED_SHORT_5_6_5|| type == GL_UNSIGNED_SHORT_5_6_5_REV)
- && format != GL_RGB)
- return GL_FALSE;
-
- /* 4_4_4_4/4_4_4_4_REV & 5_5_5_1/1_5_5_5_REV & 8_8_8_8/8_8_8_8_REV &
- * 10_10_10_2/2_10_10_10_REV are only compatible with RGBA, BGRA & ABGR_EXT.
- */
- if ((type == GL_UNSIGNED_SHORT_4_4_4_4 ||
- type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
- type == GL_UNSIGNED_SHORT_5_5_5_1 ||
- type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
- type == GL_UNSIGNED_INT_8_8_8_8 ||
- type == GL_UNSIGNED_INT_8_8_8_8_REV ||
- type == GL_UNSIGNED_INT_10_10_10_2 ||
- type == GL_UNSIGNED_INT_2_10_10_10_REV) &&
- (format != GL_RGBA &&
- format != GL_BGRA)) {
- return GL_FALSE;
- }
-
- return GL_TRUE;
-} /* isLegalFormatForPackedPixelType() */
-
-static GLboolean isLegalLevels(GLint userLevel,GLint baseLevel,GLint maxLevel,
- GLint totalLevels)
-{
- if (baseLevel < 0 || baseLevel < userLevel || maxLevel < baseLevel ||
- totalLevels < maxLevel)
- return GL_FALSE;
- else return GL_TRUE;
-} /* isLegalLevels() */
-
-/* Given user requested texture size, determine if it fits. If it
- * doesn't then halve both sides and make the determination again
- * until it does fit (for IR only).
- * Note that proxy textures are not implemented in RE* even though
- * they advertise the texture extension.
- * Note that proxy textures are implemented but not according to spec in
- * IMPACT*.
- */
-static void closestFit(GLenum target, GLint width, GLint height,
- GLint internalFormat, GLenum format, GLenum type,
- GLint *newWidth, GLint *newHeight)
-{
- /* Use proxy textures if OpenGL version is >= 1.1 */
- if ( (strtod((const char *)glGetString(GL_VERSION),NULL) >= 1.1)
- ) {
- GLint widthPowerOf2= nearestPower(width);
- GLint heightPowerOf2= nearestPower(height);
- GLint proxyWidth;
-
- do {
- /* compute level 1 width & height, clamping each at 1 */
- GLint widthAtLevelOne= (widthPowerOf2 > 1) ?
- widthPowerOf2 >> 1 :
- widthPowerOf2;
- GLint heightAtLevelOne= (heightPowerOf2 > 1) ?
- heightPowerOf2 >> 1 :
- heightPowerOf2;
- GLenum proxyTarget;
- assert(widthAtLevelOne > 0); assert(heightAtLevelOne > 0);
-
- /* does width x height at level 1 & all their mipmaps fit? */
- if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) {
- proxyTarget = GL_PROXY_TEXTURE_2D;
- glTexImage2D(proxyTarget, 1, /* must be non-zero */
- internalFormat,
- widthAtLevelOne,heightAtLevelOne,0,format,type,NULL);
- } else
-#if defined(GL_ARB_texture_cube_map)
- if ((target == GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB) ||
- (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB) ||
- (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB) ||
- (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB) ||
- (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB) ||
- (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) {
- proxyTarget = GL_PROXY_TEXTURE_CUBE_MAP_ARB;
- glTexImage2D(proxyTarget, 1, /* must be non-zero */
- internalFormat,
- widthAtLevelOne,heightAtLevelOne,0,format,type,NULL);
- } else
-#endif /* GL_ARB_texture_cube_map */
- {
- assert(target == GL_TEXTURE_1D || target == GL_PROXY_TEXTURE_1D);
- proxyTarget = GL_PROXY_TEXTURE_1D;
- glTexImage1D(proxyTarget, 1, /* must be non-zero */
- internalFormat,widthAtLevelOne,0,format,type,NULL);
- }
- glGetTexLevelParameteriv(proxyTarget, 1,GL_TEXTURE_WIDTH,&proxyWidth);
- /* does it fit??? */
- if (proxyWidth == 0) { /* nope, so try again with these sizes */
- if (widthPowerOf2 == 1 && heightPowerOf2 == 1) {
- /* An 1x1 texture couldn't fit for some reason, so
- * break out. This should never happen. But things
- * happen. The disadvantage with this if-statement is
- * that we will never be aware of when this happens
- * since it will silently branch out.
- */
- goto noProxyTextures;
- }
- widthPowerOf2= widthAtLevelOne;
- heightPowerOf2= heightAtLevelOne;
- }
- /* else it does fit */
- } while (proxyWidth == 0);
- /* loop must terminate! */
-
- /* return the width & height at level 0 that fits */
- *newWidth= widthPowerOf2;
- *newHeight= heightPowerOf2;
-/*printf("Proxy Textures\n");*/
- } /* if gluCheckExtension() */
- else { /* no texture extension, so do this instead */
- GLint maxsize;
-
-noProxyTextures:
-
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
- /* clamp user's texture sizes to maximum sizes, if necessary */
- *newWidth = nearestPower(width);
- if (*newWidth > maxsize) *newWidth = maxsize;
- *newHeight = nearestPower(height);
- if (*newHeight > maxsize) *newHeight = maxsize;
-/*printf("NO proxy textures\n");*/
- }
-} /* closestFit() */
-
-GLint GLAPIENTRY
-gluScaleImage(GLenum format, GLsizei widthin, GLsizei heightin,
- GLenum typein, const void *datain,
- GLsizei widthout, GLsizei heightout, GLenum typeout,
- void *dataout)
-{
- int components;
- GLushort *beforeImage;
- GLushort *afterImage;
- PixelStorageModes psm;
-
- if (widthin == 0 || heightin == 0 || widthout == 0 || heightout == 0) {
- return 0;
- }
- if (widthin < 0 || heightin < 0 || widthout < 0 || heightout < 0) {
- return GLU_INVALID_VALUE;
- }
- if (!legalFormat(format) || !legalType(typein) || !legalType(typeout)) {
- return GLU_INVALID_ENUM;
- }
- if (!isLegalFormatForPackedPixelType(format, typein)) {
- return GLU_INVALID_OPERATION;
- }
- if (!isLegalFormatForPackedPixelType(format, typeout)) {
- return GLU_INVALID_OPERATION;
- }
- beforeImage =
- malloc(image_size(widthin, heightin, format, GL_UNSIGNED_SHORT));
- afterImage =
- malloc(image_size(widthout, heightout, format, GL_UNSIGNED_SHORT));
- if (beforeImage == NULL || afterImage == NULL) {
- free(beforeImage);
- free(afterImage);
- return GLU_OUT_OF_MEMORY;
- }
-
- retrieveStoreModes(&psm);
- fill_image(&psm,widthin, heightin, format, typein, is_index(format),
- datain, beforeImage);
- components = elements_per_group(format, 0);
- scale_internal(components, widthin, heightin, beforeImage,
- widthout, heightout, afterImage);
- empty_image(&psm,widthout, heightout, format, typeout,
- is_index(format), afterImage, dataout);
- free((GLbyte *) beforeImage);
- free((GLbyte *) afterImage);
-
- return 0;
-}
-
-int gluBuild1DMipmapLevelsCore(GLenum target, GLint internalFormat,
- GLsizei width,
- GLsizei widthPowerOf2,
- GLenum format, GLenum type,
- GLint userLevel, GLint baseLevel,GLint maxLevel,
- const void *data)
-{
- GLint newwidth;
- GLint level, levels;
- GLushort *newImage;
- GLint newImage_width;
- GLushort *otherImage;
- GLushort *imageTemp;
- GLint memreq;
- GLint cmpts;
- PixelStorageModes psm;
-
- assert(checkMipmapArgs(internalFormat,format,type) == 0);
- assert(width >= 1);
-
- otherImage = NULL;
-
- newwidth= widthPowerOf2;
- levels = computeLog(newwidth);
-
- levels+= userLevel;
-
- retrieveStoreModes(&psm);
- newImage = (GLushort *)
- malloc(image_size(width, 1, format, GL_UNSIGNED_SHORT));
- newImage_width = width;
- if (newImage == NULL) {
- return GLU_OUT_OF_MEMORY;
- }
- fill_image(&psm,width, 1, format, type, is_index(format),
- data, newImage);
- cmpts = elements_per_group(format,type);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- /*
- ** If swap_bytes was set, swapping occurred in fill_image.
- */
- glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
-
- for (level = userLevel; level <= levels; level++) {
- if (newImage_width == newwidth) {
- /* Use newImage for this level */
- if (baseLevel <= level && level <= maxLevel) {
- glTexImage1D(target, level, internalFormat, newImage_width,
- 0, format, GL_UNSIGNED_SHORT, (void *) newImage);
- }
- } else {
- if (otherImage == NULL) {
- memreq = image_size(newwidth, 1, format, GL_UNSIGNED_SHORT);
- otherImage = (GLushort *) malloc(memreq);
- if (otherImage == NULL) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
- free(newImage);
- return GLU_OUT_OF_MEMORY;
- }
- }
- scale_internal(cmpts, newImage_width, 1, newImage,
- newwidth, 1, otherImage);
- /* Swap newImage and otherImage */
- imageTemp = otherImage;
- otherImage = newImage;
- newImage = imageTemp;
-
- newImage_width = newwidth;
- if (baseLevel <= level && level <= maxLevel) {
- glTexImage1D(target, level, internalFormat, newImage_width,
- 0, format, GL_UNSIGNED_SHORT, (void *) newImage);
- }
- }
- if (newwidth > 1) newwidth /= 2;
- }
- glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
-
- free((GLbyte *) newImage);
- if (otherImage) {
- free((GLbyte *) otherImage);
- }
- return 0;
-}
-
-GLint GLAPIENTRY
-gluBuild1DMipmapLevels(GLenum target, GLint internalFormat,
- GLsizei width,
- GLenum format, GLenum type,
- GLint userLevel, GLint baseLevel, GLint maxLevel,
- const void *data)
-{
- int levels;
-
- int rc= checkMipmapArgs(internalFormat,format,type);
- if (rc != 0) return rc;
-
- if (width < 1) {
- return GLU_INVALID_VALUE;
- }
-
- levels = computeLog(width);
-
- levels+= userLevel;
- if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels))
- return GLU_INVALID_VALUE;
-
- return gluBuild1DMipmapLevelsCore(target, internalFormat,
- width,
- width,format, type,
- userLevel, baseLevel, maxLevel,
- data);
-} /* gluBuild1DMipmapLevels() */
-
-GLint GLAPIENTRY
-gluBuild1DMipmaps(GLenum target, GLint internalFormat, GLsizei width,
- GLenum format, GLenum type,
- const void *data)
-{
- GLint widthPowerOf2;
- int levels;
- GLint dummy;
-
- int rc= checkMipmapArgs(internalFormat,format,type);
- if (rc != 0) return rc;
-
- if (width < 1) {
- return GLU_INVALID_VALUE;
- }
-
- closestFit(target,width,1,internalFormat,format,type,&widthPowerOf2,&dummy);
- levels = computeLog(widthPowerOf2);
-
- return gluBuild1DMipmapLevelsCore(target,internalFormat,
- width,
- widthPowerOf2,
- format,type,0,0,levels,data);
-}
-
-static int bitmapBuild2DMipmaps(GLenum target, GLint internalFormat,
- GLint width, GLint height, GLenum format,
- GLenum type, const void *data)
-{
- GLint newwidth, newheight;
- GLint level, levels;
- GLushort *newImage;
- GLint newImage_width;
- GLint newImage_height;
- GLushort *otherImage;
- GLushort *imageTemp;
- GLint memreq;
- GLint cmpts;
- PixelStorageModes psm;
-
- retrieveStoreModes(&psm);
-
-#if 0
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
- newwidth = nearestPower(width);
- if (newwidth > maxsize) newwidth = maxsize;
- newheight = nearestPower(height);
- if (newheight > maxsize) newheight = maxsize;
-#else
- closestFit(target,width,height,internalFormat,format,type,
- &newwidth,&newheight);
-#endif
- levels = computeLog(newwidth);
- level = computeLog(newheight);
- if (level > levels) levels=level;
-
- otherImage = NULL;
- newImage = (GLushort *)
- malloc(image_size(width, height, format, GL_UNSIGNED_SHORT));
- newImage_width = width;
- newImage_height = height;
- if (newImage == NULL) {
- return GLU_OUT_OF_MEMORY;
- }
-
- fill_image(&psm,width, height, format, type, is_index(format),
- data, newImage);
-
- cmpts = elements_per_group(format,type);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- /*
- ** If swap_bytes was set, swapping occurred in fill_image.
- */
- glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
-
- for (level = 0; level <= levels; level++) {
- if (newImage_width == newwidth && newImage_height == newheight) { /* Use newImage for this level */
- glTexImage2D(target, level, internalFormat, newImage_width,
- newImage_height, 0, format, GL_UNSIGNED_SHORT,
- (void *) newImage);
- } else {
- if (otherImage == NULL) {
- memreq =
- image_size(newwidth, newheight, format, GL_UNSIGNED_SHORT);
- otherImage = (GLushort *) malloc(memreq);
- if (otherImage == NULL) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
- free(newImage);
- return GLU_OUT_OF_MEMORY;
- }
- }
- scale_internal(cmpts, newImage_width, newImage_height, newImage,
- newwidth, newheight, otherImage);
- /* Swap newImage and otherImage */
- imageTemp = otherImage;
- otherImage = newImage;
- newImage = imageTemp;
-
- newImage_width = newwidth;
- newImage_height = newheight;
- glTexImage2D(target, level, internalFormat, newImage_width,
- newImage_height, 0, format, GL_UNSIGNED_SHORT,
- (void *) newImage);
- }
- if (newwidth > 1) newwidth /= 2;
- if (newheight > 1) newheight /= 2;
- }
- glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
-
- free((GLbyte *) newImage);
- if (otherImage) {
- free((GLbyte *) otherImage);
- }
- return 0;
-}
-
-/* To make swapping images less error prone */
-#define __GLU_INIT_SWAP_IMAGE void *tmpImage
-#define __GLU_SWAP_IMAGE(a,b) tmpImage = a; a = b; b = tmpImage;
-
-static int gluBuild2DMipmapLevelsCore(GLenum target, GLint internalFormat,
- GLsizei width, GLsizei height,
- GLsizei widthPowerOf2,
- GLsizei heightPowerOf2,
- GLenum format, GLenum type,
- GLint userLevel,
- GLint baseLevel,GLint maxLevel,
- const void *data)
-{
- GLint newwidth, newheight;
- GLint level, levels;
- const void *usersImage; /* passed from user. Don't touch! */
- void *srcImage, *dstImage; /* scratch area to build mipmapped images */
- __GLU_INIT_SWAP_IMAGE;
- GLint memreq;
- GLint cmpts;
-
- GLint myswap_bytes, groups_per_line, element_size, group_size;
- GLint rowsize, padding;
- PixelStorageModes psm;
-
- assert(checkMipmapArgs(internalFormat,format,type) == 0);
- assert(width >= 1 && height >= 1);
-
- if(type == GL_BITMAP) {
- return bitmapBuild2DMipmaps(target, internalFormat, width, height,
- format, type, data);
- }
-
- srcImage = dstImage = NULL;
-
- newwidth= widthPowerOf2;
- newheight= heightPowerOf2;
- levels = computeLog(newwidth);
- level = computeLog(newheight);
- if (level > levels) levels=level;
-
- levels+= userLevel;
-
- retrieveStoreModes(&psm);
- myswap_bytes = psm.unpack_swap_bytes;
- cmpts = elements_per_group(format,type);
- if (psm.unpack_row_length > 0) {
- groups_per_line = psm.unpack_row_length;
- } else {
- groups_per_line = width;
- }
-
- element_size = bytes_per_element(type);
- group_size = element_size * cmpts;
- if (element_size == 1) myswap_bytes = 0;
-
- rowsize = groups_per_line * group_size;
- padding = (rowsize % psm.unpack_alignment);
- if (padding) {
- rowsize += psm.unpack_alignment - padding;
- }
- usersImage = (const GLubyte *) data + psm.unpack_skip_rows * rowsize +
- psm.unpack_skip_pixels * group_size;
-
- glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-
- level = userLevel;
-
- /* already power-of-two square */
- if (width == newwidth && height == newheight) {
- /* Use usersImage for level userLevel */
- if (baseLevel <= level && level <= maxLevel) {
- glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
- glTexImage2D(target, level, internalFormat, width,
- height, 0, format, type,
- usersImage);
- }
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- if(levels == 0) { /* we're done. clean up and return */
- glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
- return 0;
- }
- {
- int nextWidth= newwidth/2;
- int nextHeight= newheight/2;
-
- /* clamp to 1 */
- if (nextWidth < 1) nextWidth= 1;
- if (nextHeight < 1) nextHeight= 1;
- memreq = image_size(nextWidth, nextHeight, format, type);
- }
-
- switch(type) {
- case GL_UNSIGNED_BYTE:
- dstImage = (GLubyte *)malloc(memreq);
- break;
- case GL_BYTE:
- dstImage = (GLbyte *)malloc(memreq);
- break;
- case GL_UNSIGNED_SHORT:
- dstImage = (GLushort *)malloc(memreq);
- break;
- case GL_SHORT:
- dstImage = (GLshort *)malloc(memreq);
- break;
- case GL_UNSIGNED_INT:
- dstImage = (GLuint *)malloc(memreq);
- break;
- case GL_INT:
- dstImage = (GLint *)malloc(memreq);
- break;
- case GL_FLOAT:
- dstImage = (GLfloat *)malloc(memreq);
- break;
- case GL_UNSIGNED_BYTE_3_3_2:
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- dstImage = (GLubyte *)malloc(memreq);
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- dstImage = (GLushort *)malloc(memreq);
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- case GL_UNSIGNED_INT_10_10_10_2:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- dstImage = (GLuint *)malloc(memreq);
- break;
- default:
- return GLU_INVALID_ENUM;
- }
- if (dstImage == NULL) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
- return GLU_OUT_OF_MEMORY;
- }
- else
- switch(type) {
- case GL_UNSIGNED_BYTE:
- halveImage_ubyte(cmpts, width, height,
- (const GLubyte *)usersImage, (GLubyte *)dstImage,
- element_size, rowsize, group_size);
- break;
- case GL_BYTE:
- halveImage_byte(cmpts, width, height,
- (const GLbyte *)usersImage, (GLbyte *)dstImage,
- element_size, rowsize, group_size);
- break;
- case GL_UNSIGNED_SHORT:
- halveImage_ushort(cmpts, width, height,
- (const GLushort *)usersImage, (GLushort *)dstImage,
- element_size, rowsize, group_size, myswap_bytes);
- break;
- case GL_SHORT:
- halveImage_short(cmpts, width, height,
- (const GLshort *)usersImage, (GLshort *)dstImage,
- element_size, rowsize, group_size, myswap_bytes);
- break;
- case GL_UNSIGNED_INT:
- halveImage_uint(cmpts, width, height,
- (const GLuint *)usersImage, (GLuint *)dstImage,
- element_size, rowsize, group_size, myswap_bytes);
- break;
- case GL_INT:
- halveImage_int(cmpts, width, height,
- (const GLint *)usersImage, (GLint *)dstImage,
- element_size, rowsize, group_size, myswap_bytes);
- break;
- case GL_FLOAT:
- halveImage_float(cmpts, width, height,
- (const GLfloat *)usersImage, (GLfloat *)dstImage,
- element_size, rowsize, group_size, myswap_bytes);
- break;
- case GL_UNSIGNED_BYTE_3_3_2:
- assert(format == GL_RGB);
- halveImagePackedPixel(3,extract332,shove332,
- width,height,usersImage,dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- assert(format == GL_RGB);
- halveImagePackedPixel(3,extract233rev,shove233rev,
- width,height,usersImage,dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- halveImagePackedPixel(3,extract565,shove565,
- width,height,usersImage,dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- halveImagePackedPixel(3,extract565rev,shove565rev,
- width,height,usersImage,dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- case GL_UNSIGNED_SHORT_4_4_4_4:
- halveImagePackedPixel(4,extract4444,shove4444,
- width,height,usersImage,dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- halveImagePackedPixel(4,extract4444rev,shove4444rev,
- width,height,usersImage,dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- case GL_UNSIGNED_SHORT_5_5_5_1:
- halveImagePackedPixel(4,extract5551,shove5551,
- width,height,usersImage,dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- halveImagePackedPixel(4,extract1555rev,shove1555rev,
- width,height,usersImage,dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- halveImagePackedPixel(4,extract8888,shove8888,
- width,height,usersImage,dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- halveImagePackedPixel(4,extract8888rev,shove8888rev,
- width,height,usersImage,dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- case GL_UNSIGNED_INT_10_10_10_2:
- halveImagePackedPixel(4,extract1010102,shove1010102,
- width,height,usersImage,dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- halveImagePackedPixel(4,extract2101010rev,shove2101010rev,
- width,height,usersImage,dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- default:
- assert(0);
- break;
- }
- newwidth = width/2;
- newheight = height/2;
- /* clamp to 1 */
- if (newwidth < 1) newwidth= 1;
- if (newheight < 1) newheight= 1;
-
- myswap_bytes = 0;
- rowsize = newwidth * group_size;
- memreq = image_size(newwidth, newheight, format, type);
- /* Swap srcImage and dstImage */
- __GLU_SWAP_IMAGE(srcImage,dstImage);
- switch(type) {
- case GL_UNSIGNED_BYTE:
- dstImage = (GLubyte *)malloc(memreq);
- break;
- case GL_BYTE:
- dstImage = (GLbyte *)malloc(memreq);
- break;
- case GL_UNSIGNED_SHORT:
- dstImage = (GLushort *)malloc(memreq);
- break;
- case GL_SHORT:
- dstImage = (GLshort *)malloc(memreq);
- break;
- case GL_UNSIGNED_INT:
- dstImage = (GLuint *)malloc(memreq);
- break;
- case GL_INT:
- dstImage = (GLint *)malloc(memreq);
- break;
- case GL_FLOAT:
- dstImage = (GLfloat *)malloc(memreq);
- break;
- case GL_UNSIGNED_BYTE_3_3_2:
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- dstImage = (GLubyte *)malloc(memreq);
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- dstImage = (GLushort *)malloc(memreq);
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- case GL_UNSIGNED_INT_10_10_10_2:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- dstImage = (GLuint *)malloc(memreq);
- break;
- default:
- return GLU_INVALID_ENUM;
- }
- if (dstImage == NULL) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
- free(srcImage);
- return GLU_OUT_OF_MEMORY;
- }
- /* level userLevel+1 is in srcImage; level userLevel already saved */
- level = userLevel+1;
- } else { /* user's image is *not* nice power-of-2 sized square */
- memreq = image_size(newwidth, newheight, format, type);
- switch(type) {
- case GL_UNSIGNED_BYTE:
- dstImage = (GLubyte *)malloc(memreq);
- break;
- case GL_BYTE:
- dstImage = (GLbyte *)malloc(memreq);
- break;
- case GL_UNSIGNED_SHORT:
- dstImage = (GLushort *)malloc(memreq);
- break;
- case GL_SHORT:
- dstImage = (GLshort *)malloc(memreq);
- break;
- case GL_UNSIGNED_INT:
- dstImage = (GLuint *)malloc(memreq);
- break;
- case GL_INT:
- dstImage = (GLint *)malloc(memreq);
- break;
- case GL_FLOAT:
- dstImage = (GLfloat *)malloc(memreq);
- break;
- case GL_UNSIGNED_BYTE_3_3_2:
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- dstImage = (GLubyte *)malloc(memreq);
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- dstImage = (GLushort *)malloc(memreq);
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- case GL_UNSIGNED_INT_10_10_10_2:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- dstImage = (GLuint *)malloc(memreq);
- break;
- default:
- return GLU_INVALID_ENUM;
- }
-
- if (dstImage == NULL) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
- return GLU_OUT_OF_MEMORY;
- }
-
- switch(type) {
- case GL_UNSIGNED_BYTE:
- scale_internal_ubyte(cmpts, width, height,
- (const GLubyte *)usersImage, newwidth, newheight,
- (GLubyte *)dstImage, element_size,
- rowsize, group_size);
- break;
- case GL_BYTE:
- scale_internal_byte(cmpts, width, height,
- (const GLbyte *)usersImage, newwidth, newheight,
- (GLbyte *)dstImage, element_size,
- rowsize, group_size);
- break;
- case GL_UNSIGNED_SHORT:
- scale_internal_ushort(cmpts, width, height,
- (const GLushort *)usersImage, newwidth, newheight,
- (GLushort *)dstImage, element_size,
- rowsize, group_size, myswap_bytes);
- break;
- case GL_SHORT:
- scale_internal_short(cmpts, width, height,
- (const GLshort *)usersImage, newwidth, newheight,
- (GLshort *)dstImage, element_size,
- rowsize, group_size, myswap_bytes);
- break;
- case GL_UNSIGNED_INT:
- scale_internal_uint(cmpts, width, height,
- (const GLuint *)usersImage, newwidth, newheight,
- (GLuint *)dstImage, element_size,
- rowsize, group_size, myswap_bytes);
- break;
- case GL_INT:
- scale_internal_int(cmpts, width, height,
- (const GLint *)usersImage, newwidth, newheight,
- (GLint *)dstImage, element_size,
- rowsize, group_size, myswap_bytes);
- break;
- case GL_FLOAT:
- scale_internal_float(cmpts, width, height,
- (const GLfloat *)usersImage, newwidth, newheight,
- (GLfloat *)dstImage, element_size,
- rowsize, group_size, myswap_bytes);
- break;
- case GL_UNSIGNED_BYTE_3_3_2:
- scaleInternalPackedPixel(3,extract332,shove332,
- width, height,usersImage,
- newwidth,newheight,(void *)dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- scaleInternalPackedPixel(3,extract233rev,shove233rev,
- width, height,usersImage,
- newwidth,newheight,(void *)dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- scaleInternalPackedPixel(3,extract565,shove565,
- width, height,usersImage,
- newwidth,newheight,(void *)dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- scaleInternalPackedPixel(3,extract565rev,shove565rev,
- width, height,usersImage,
- newwidth,newheight,(void *)dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- case GL_UNSIGNED_SHORT_4_4_4_4:
- scaleInternalPackedPixel(4,extract4444,shove4444,
- width, height,usersImage,
- newwidth,newheight,(void *)dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- scaleInternalPackedPixel(4,extract4444rev,shove4444rev,
- width, height,usersImage,
- newwidth,newheight,(void *)dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- case GL_UNSIGNED_SHORT_5_5_5_1:
- scaleInternalPackedPixel(4,extract5551,shove5551,
- width, height,usersImage,
- newwidth,newheight,(void *)dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- scaleInternalPackedPixel(4,extract1555rev,shove1555rev,
- width, height,usersImage,
- newwidth,newheight,(void *)dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- scaleInternalPackedPixel(4,extract8888,shove8888,
- width, height,usersImage,
- newwidth,newheight,(void *)dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- scaleInternalPackedPixel(4,extract8888rev,shove8888rev,
- width, height,usersImage,
- newwidth,newheight,(void *)dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- case GL_UNSIGNED_INT_10_10_10_2:
- scaleInternalPackedPixel(4,extract1010102,shove1010102,
- width, height,usersImage,
- newwidth,newheight,(void *)dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- scaleInternalPackedPixel(4,extract2101010rev,shove2101010rev,
- width, height,usersImage,
- newwidth,newheight,(void *)dstImage,
- element_size,rowsize,myswap_bytes);
- break;
- default:
- assert(0);
- break;
- }
- myswap_bytes = 0;
- rowsize = newwidth * group_size;
- /* Swap dstImage and srcImage */
- __GLU_SWAP_IMAGE(srcImage,dstImage);
-
- if(levels != 0) { /* use as little memory as possible */
- {
- int nextWidth= newwidth/2;
- int nextHeight= newheight/2;
- if (nextWidth < 1) nextWidth= 1;
- if (nextHeight < 1) nextHeight= 1;
-
- memreq = image_size(nextWidth, nextHeight, format, type);
- }
-
- switch(type) {
- case GL_UNSIGNED_BYTE:
- dstImage = (GLubyte *)malloc(memreq);
- break;
- case GL_BYTE:
- dstImage = (GLbyte *)malloc(memreq);
- break;
- case GL_UNSIGNED_SHORT:
- dstImage = (GLushort *)malloc(memreq);
- break;
- case GL_SHORT:
- dstImage = (GLshort *)malloc(memreq);
- break;
- case GL_UNSIGNED_INT:
- dstImage = (GLuint *)malloc(memreq);
- break;
- case GL_INT:
- dstImage = (GLint *)malloc(memreq);
- break;
- case GL_FLOAT:
- dstImage = (GLfloat *)malloc(memreq);
- break;
- case GL_UNSIGNED_BYTE_3_3_2:
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- dstImage = (GLubyte *)malloc(memreq);
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- dstImage = (GLushort *)malloc(memreq);
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- case GL_UNSIGNED_INT_10_10_10_2:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- dstImage = (GLuint *)malloc(memreq);
- break;
- default:
- return GLU_INVALID_ENUM;
- }
- if (dstImage == NULL) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
- free(srcImage);
- return GLU_OUT_OF_MEMORY;
- }
- }
- /* level userLevel is in srcImage; nothing saved yet */
- level = userLevel;
- }
-
- glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
- if (baseLevel <= level && level <= maxLevel) {
- glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
- format, type, (void *)srcImage);
- }
-
- level++; /* update current level for the loop */
- for (; level <= levels; level++) {
- switch(type) {
- case GL_UNSIGNED_BYTE:
- halveImage_ubyte(cmpts, newwidth, newheight,
- (GLubyte *)srcImage, (GLubyte *)dstImage, element_size,
- rowsize, group_size);
- break;
- case GL_BYTE:
- halveImage_byte(cmpts, newwidth, newheight,
- (GLbyte *)srcImage, (GLbyte *)dstImage, element_size,
- rowsize, group_size);
- break;
- case GL_UNSIGNED_SHORT:
- halveImage_ushort(cmpts, newwidth, newheight,
- (GLushort *)srcImage, (GLushort *)dstImage, element_size,
- rowsize, group_size, myswap_bytes);
- break;
- case GL_SHORT:
- halveImage_short(cmpts, newwidth, newheight,
- (GLshort *)srcImage, (GLshort *)dstImage, element_size,
- rowsize, group_size, myswap_bytes);
- break;
- case GL_UNSIGNED_INT:
- halveImage_uint(cmpts, newwidth, newheight,
- (GLuint *)srcImage, (GLuint *)dstImage, element_size,
- rowsize, group_size, myswap_bytes);
- break;
- case GL_INT:
- halveImage_int(cmpts, newwidth, newheight,
- (GLint *)srcImage, (GLint *)dstImage, element_size,
- rowsize, group_size, myswap_bytes);
- break;
- case GL_FLOAT:
- halveImage_float(cmpts, newwidth, newheight,
- (GLfloat *)srcImage, (GLfloat *)dstImage, element_size,
- rowsize, group_size, myswap_bytes);
- break;
- case GL_UNSIGNED_BYTE_3_3_2:
- halveImagePackedPixel(3,extract332,shove332,
- newwidth,newheight,
- srcImage,dstImage,element_size,rowsize,
- myswap_bytes);
- break;
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- halveImagePackedPixel(3,extract233rev,shove233rev,
- newwidth,newheight,
- srcImage,dstImage,element_size,rowsize,
- myswap_bytes);
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- halveImagePackedPixel(3,extract565,shove565,
- newwidth,newheight,
- srcImage,dstImage,element_size,rowsize,
- myswap_bytes);
- break;
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- halveImagePackedPixel(3,extract565rev,shove565rev,
- newwidth,newheight,
- srcImage,dstImage,element_size,rowsize,
- myswap_bytes);
- break;
- case GL_UNSIGNED_SHORT_4_4_4_4:
- halveImagePackedPixel(4,extract4444,shove4444,
- newwidth,newheight,
- srcImage,dstImage,element_size,rowsize,
- myswap_bytes);
- break;
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- halveImagePackedPixel(4,extract4444rev,shove4444rev,
- newwidth,newheight,
- srcImage,dstImage,element_size,rowsize,
- myswap_bytes);
- break;
- case GL_UNSIGNED_SHORT_5_5_5_1:
- halveImagePackedPixel(4,extract5551,shove5551,
- newwidth,newheight,
- srcImage,dstImage,element_size,rowsize,
- myswap_bytes);
- break;
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- halveImagePackedPixel(4,extract1555rev,shove1555rev,
- newwidth,newheight,
- srcImage,dstImage,element_size,rowsize,
- myswap_bytes);
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- halveImagePackedPixel(4,extract8888,shove8888,
- newwidth,newheight,
- srcImage,dstImage,element_size,rowsize,
- myswap_bytes);
- break;
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- halveImagePackedPixel(4,extract8888rev,shove8888rev,
- newwidth,newheight,
- srcImage,dstImage,element_size,rowsize,
- myswap_bytes);
- break;
- case GL_UNSIGNED_INT_10_10_10_2:
- halveImagePackedPixel(4,extract1010102,shove1010102,
- newwidth,newheight,
- srcImage,dstImage,element_size,rowsize,
- myswap_bytes);
- break;
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- halveImagePackedPixel(4,extract2101010rev,shove2101010rev,
- newwidth,newheight,
- srcImage,dstImage,element_size,rowsize,
- myswap_bytes);
- break;
- default:
- assert(0);
- break;
- }
-
- __GLU_SWAP_IMAGE(srcImage,dstImage);
-
- if (newwidth > 1) { newwidth /= 2; rowsize /= 2;}
- if (newheight > 1) newheight /= 2;
- {
- /* compute amount to pad per row, if any */
- int rowPad= rowsize % psm.unpack_alignment;
-
- /* should row be padded? */
- if (rowPad == 0) { /* nope, row should not be padded */
- /* call tex image with srcImage untouched since it's not padded */
- if (baseLevel <= level && level <= maxLevel) {
- glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
- format, type, (void *) srcImage);
- }
- }
- else { /* yes, row should be padded */
- /* compute length of new row in bytes, including padding */
- int newRowLength= rowsize + psm.unpack_alignment - rowPad;
- int ii; unsigned char *dstTrav, *srcTrav; /* indices for copying */
-
- /* allocate new image for mipmap of size newRowLength x newheight */
- void *newMipmapImage= malloc((size_t) (newRowLength*newheight));
- if (newMipmapImage == NULL) {
- /* out of memory so return */
- glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
- return GLU_OUT_OF_MEMORY;
- }
-
- /* copy image from srcImage into newMipmapImage by rows */
- for (ii= 0,
- dstTrav= (unsigned char *) newMipmapImage,
- srcTrav= (unsigned char *) srcImage;
- ii< newheight;
- ii++,
- dstTrav+= newRowLength, /* make sure the correct distance... */
- srcTrav+= rowsize) { /* ...is skipped */
- memcpy(dstTrav,srcTrav,rowsize);
- /* note that the pad bytes are not visited and will contain
- * garbage, which is ok.
- */
- }
-
- /* ...and use this new image for mipmapping instead */
- if (baseLevel <= level && level <= maxLevel) {
- glTexImage2D(target, level, internalFormat, newwidth, newheight, 0,
- format, type, newMipmapImage);
- }
- free(newMipmapImage); /* don't forget to free it! */
- } /* else */
- }
- } /* for level */
- glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
-
- free(srcImage); /*if you get to here, a srcImage has always been malloc'ed*/
- if (dstImage) { /* if it's non-rectangular and only 1 level */
- free(dstImage);
- }
- return 0;
-} /* gluBuild2DMipmapLevelsCore() */
-
-GLint GLAPIENTRY
-gluBuild2DMipmapLevels(GLenum target, GLint internalFormat,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- GLint userLevel, GLint baseLevel, GLint maxLevel,
- const void *data)
-{
- int level, levels;
-
- int rc= checkMipmapArgs(internalFormat,format,type);
- if (rc != 0) return rc;
-
- if (width < 1 || height < 1) {
- return GLU_INVALID_VALUE;
- }
-
- levels = computeLog(width);
- level = computeLog(height);
- if (level > levels) levels=level;
-
- levels+= userLevel;
- if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels))
- return GLU_INVALID_VALUE;
-
- return gluBuild2DMipmapLevelsCore(target, internalFormat,
- width, height,
- width, height,
- format, type,
- userLevel, baseLevel, maxLevel,
- data);
-} /* gluBuild2DMipmapLevels() */
-
-GLint GLAPIENTRY
-gluBuild2DMipmaps(GLenum target, GLint internalFormat,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const void *data)
-{
- GLint widthPowerOf2, heightPowerOf2;
- int level, levels;
-
- int rc= checkMipmapArgs(internalFormat,format,type);
- if (rc != 0) return rc;
-
- if (width < 1 || height < 1) {
- return GLU_INVALID_VALUE;
- }
-
- closestFit(target,width,height,internalFormat,format,type,
- &widthPowerOf2,&heightPowerOf2);
-
- levels = computeLog(widthPowerOf2);
- level = computeLog(heightPowerOf2);
- if (level > levels) levels=level;
-
- return gluBuild2DMipmapLevelsCore(target,internalFormat,
- width, height,
- widthPowerOf2,heightPowerOf2,
- format,type,
- 0,0,levels,data);
-} /* gluBuild2DMipmaps() */
-
-#if 0
-/*
-** This routine is for the limited case in which
-** type == GL_UNSIGNED_BYTE && format != index &&
-** unpack_alignment = 1 && unpack_swap_bytes == false
-**
-** so all of the work data can be kept as ubytes instead of shorts.
-*/
-static int fastBuild2DMipmaps(const PixelStorageModes *psm,
- GLenum target, GLint components, GLint width,
- GLint height, GLenum format,
- GLenum type, void *data)
-{
- GLint newwidth, newheight;
- GLint level, levels;
- GLubyte *newImage;
- GLint newImage_width;
- GLint newImage_height;
- GLubyte *otherImage;
- GLubyte *imageTemp;
- GLint memreq;
- GLint cmpts;
-
-
-#if 0
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
- newwidth = nearestPower(width);
- if (newwidth > maxsize) newwidth = maxsize;
- newheight = nearestPower(height);
- if (newheight > maxsize) newheight = maxsize;
-#else
- closestFit(target,width,height,components,format,type,
- &newwidth,&newheight);
-#endif
- levels = computeLog(newwidth);
- level = computeLog(newheight);
- if (level > levels) levels=level;
-
- cmpts = elements_per_group(format,type);
-
- otherImage = NULL;
- /**
- ** No need to copy the user data if its in the packed correctly.
- ** Make sure that later routines don't change that data.
- */
- if (psm->unpack_skip_rows == 0 && psm->unpack_skip_pixels == 0) {
- newImage = (GLubyte *)data;
- newImage_width = width;
- newImage_height = height;
- } else {
- GLint rowsize;
- GLint groups_per_line;
- GLint elements_per_line;
- const GLubyte *start;
- const GLubyte *iter;
- GLubyte *iter2;
- GLint i, j;
-
- newImage = (GLubyte *)
- malloc(image_size(width, height, format, GL_UNSIGNED_BYTE));
- newImage_width = width;
- newImage_height = height;
- if (newImage == NULL) {
- return GLU_OUT_OF_MEMORY;
- }
-
- /*
- ** Abbreviated version of fill_image for this restricted case.
- */
- if (psm->unpack_row_length > 0) {
- groups_per_line = psm->unpack_row_length;
- } else {
- groups_per_line = width;
- }
- rowsize = groups_per_line * cmpts;
- elements_per_line = width * cmpts;
- start = (const GLubyte *) data + psm->unpack_skip_rows * rowsize +
- psm->unpack_skip_pixels * cmpts;
- iter2 = newImage;
-
- for (i = 0; i < height; i++) {
- iter = start;
- for (j = 0; j < elements_per_line; j++) {
- *iter2 = *iter;
- iter++;
- iter2++;
- }
- start += rowsize;
- }
- }
-
-
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
-
- for (level = 0; level <= levels; level++) {
- if (newImage_width == newwidth && newImage_height == newheight) {
- /* Use newImage for this level */
- glTexImage2D(target, level, components, newImage_width,
- newImage_height, 0, format, GL_UNSIGNED_BYTE,
- (void *) newImage);
- } else {
- if (otherImage == NULL) {
- memreq =
- image_size(newwidth, newheight, format, GL_UNSIGNED_BYTE);
- otherImage = (GLubyte *) malloc(memreq);
- if (otherImage == NULL) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, psm->unpack_alignment);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, psm->unpack_skip_rows);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm->unpack_skip_pixels);
- glPixelStorei(GL_UNPACK_ROW_LENGTH,psm->unpack_row_length);
- glPixelStorei(GL_UNPACK_SWAP_BYTES,psm->unpack_swap_bytes);
- return GLU_OUT_OF_MEMORY;
- }
- }
-/*
- scale_internal_ubyte(cmpts, newImage_width, newImage_height,
- newImage, newwidth, newheight, otherImage);
-*/
- /* Swap newImage and otherImage */
- imageTemp = otherImage;
- otherImage = newImage;
- newImage = imageTemp;
-
- newImage_width = newwidth;
- newImage_height = newheight;
- glTexImage2D(target, level, components, newImage_width,
- newImage_height, 0, format, GL_UNSIGNED_BYTE,
- (void *) newImage);
- }
- if (newwidth > 1) newwidth /= 2;
- if (newheight > 1) newheight /= 2;
- }
- glPixelStorei(GL_UNPACK_ALIGNMENT, psm->unpack_alignment);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, psm->unpack_skip_rows);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm->unpack_skip_pixels);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, psm->unpack_row_length);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, psm->unpack_swap_bytes);
-
- if (newImage != (const GLubyte *)data) {
- free((GLbyte *) newImage);
- }
- if (otherImage && otherImage != (const GLubyte *)data) {
- free((GLbyte *) otherImage);
- }
- return 0;
-}
-#endif
-
-/*
- * Utility Routines
- */
-static GLint elements_per_group(GLenum format, GLenum type)
-{
- /*
- * Return the number of elements per group of a specified format
- */
-
- /* If the type is packedpixels then answer is 1 (ignore format) */
- if (type == GL_UNSIGNED_BYTE_3_3_2 ||
- type == GL_UNSIGNED_BYTE_2_3_3_REV ||
- type == GL_UNSIGNED_SHORT_5_6_5 ||
- type == GL_UNSIGNED_SHORT_5_6_5_REV ||
- type == GL_UNSIGNED_SHORT_4_4_4_4 ||
- type == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
- type == GL_UNSIGNED_SHORT_5_5_5_1 ||
- type == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
- type == GL_UNSIGNED_INT_8_8_8_8 ||
- type == GL_UNSIGNED_INT_8_8_8_8_REV ||
- type == GL_UNSIGNED_INT_10_10_10_2 ||
- type == GL_UNSIGNED_INT_2_10_10_10_REV) {
- return 1;
- }
-
- /* Types are not packed pixels, so get elements per group */
- switch(format) {
- case GL_RGB:
- case GL_BGR:
- return 3;
- case GL_LUMINANCE_ALPHA:
- return 2;
- case GL_RGBA:
- case GL_BGRA:
- return 4;
- default:
- return 1;
- }
-}
-
-static GLfloat bytes_per_element(GLenum type)
-{
- /*
- * Return the number of bytes per element, based on the element type
- */
- switch(type) {
- case GL_BITMAP:
- return 1.0 / 8.0;
- case GL_UNSIGNED_SHORT:
- return(sizeof(GLushort));
- case GL_SHORT:
- return(sizeof(GLshort));
- case GL_UNSIGNED_BYTE:
- return(sizeof(GLubyte));
- case GL_BYTE:
- return(sizeof(GLbyte));
- case GL_INT:
- return(sizeof(GLint));
- case GL_UNSIGNED_INT:
- return(sizeof(GLuint));
- case GL_FLOAT:
- return(sizeof(GLfloat));
- case GL_UNSIGNED_BYTE_3_3_2:
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- return(sizeof(GLubyte));
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- return(sizeof(GLushort));
- case GL_UNSIGNED_INT_8_8_8_8:
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- case GL_UNSIGNED_INT_10_10_10_2:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- return(sizeof(GLuint));
- default:
- return 4;
- }
-}
-
-static GLint is_index(GLenum format)
-{
- return format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX;
-}
-
-/*
-** Compute memory required for internal packed array of data of given type
-** and format.
-*/
-static GLint image_size(GLint width, GLint height, GLenum format, GLenum type)
-{
- int bytes_per_row;
- int components;
-
-assert(width > 0);
-assert(height > 0);
- components = elements_per_group(format,type);
- if (type == GL_BITMAP) {
- bytes_per_row = (width + 7) / 8;
- } else {
- bytes_per_row = bytes_per_element(type) * width;
- }
- return bytes_per_row * height * components;
-}
-
-/*
-** Extract array from user's data applying all pixel store modes.
-** The internal format used is an array of unsigned shorts.
-*/
-static void fill_image(const PixelStorageModes *psm,
- GLint width, GLint height, GLenum format,
- GLenum type, GLboolean index_format,
- const void *userdata, GLushort *newimage)
-{
- GLint components;
- GLint element_size;
- GLint rowsize;
- GLint padding;
- GLint groups_per_line;
- GLint group_size;
- GLint elements_per_line;
- const GLubyte *start;
- const GLubyte *iter;
- GLushort *iter2;
- GLint i, j, k;
- GLint myswap_bytes;
-
- myswap_bytes = psm->unpack_swap_bytes;
- components = elements_per_group(format,type);
- if (psm->unpack_row_length > 0) {
- groups_per_line = psm->unpack_row_length;
- } else {
- groups_per_line = width;
- }
-
- /* All formats except GL_BITMAP fall out trivially */
- if (type == GL_BITMAP) {
- GLint bit_offset;
- GLint current_bit;
-
- rowsize = (groups_per_line * components + 7) / 8;
- padding = (rowsize % psm->unpack_alignment);
- if (padding) {
- rowsize += psm->unpack_alignment - padding;
- }
- start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize +
- (psm->unpack_skip_pixels * components / 8);
- elements_per_line = width * components;
- iter2 = newimage;
- for (i = 0; i < height; i++) {
- iter = start;
- bit_offset = (psm->unpack_skip_pixels * components) % 8;
- for (j = 0; j < elements_per_line; j++) {
- /* Retrieve bit */
- if (psm->unpack_lsb_first) {
- current_bit = iter[0] & (1 << bit_offset);
- } else {
- current_bit = iter[0] & (1 << (7 - bit_offset));
- }
- if (current_bit) {
- if (index_format) {
- *iter2 = 1;
- } else {
- *iter2 = 65535;
- }
- } else {
- *iter2 = 0;
- }
- bit_offset++;
- if (bit_offset == 8) {
- bit_offset = 0;
- iter++;
- }
- iter2++;
- }
- start += rowsize;
- }
- } else {
- element_size = bytes_per_element(type);
- group_size = element_size * components;
- if (element_size == 1) myswap_bytes = 0;
-
- rowsize = groups_per_line * group_size;
- padding = (rowsize % psm->unpack_alignment);
- if (padding) {
- rowsize += psm->unpack_alignment - padding;
- }
- start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize +
- psm->unpack_skip_pixels * group_size;
- elements_per_line = width * components;
-
- iter2 = newimage;
- for (i = 0; i < height; i++) {
- iter = start;
- for (j = 0; j < elements_per_line; j++) {
- Type_Widget widget;
- float extractComponents[4];
-
- switch(type) {
- case GL_UNSIGNED_BYTE_3_3_2:
- extract332(0,iter,extractComponents);
- for (k = 0; k < 3; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- extract233rev(0,iter,extractComponents);
- for (k = 0; k < 3; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_UNSIGNED_BYTE:
- if (index_format) {
- *iter2++ = *iter;
- } else {
- *iter2++ = (*iter) * 257;
- }
- break;
- case GL_BYTE:
- if (index_format) {
- *iter2++ = *((const GLbyte *) iter);
- } else {
- /* rough approx */
- *iter2++ = (*((const GLbyte *) iter)) * 516;
- }
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- extract565(myswap_bytes,iter,extractComponents);
- for (k = 0; k < 3; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- extract565rev(myswap_bytes,iter,extractComponents);
- for (k = 0; k < 3; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_UNSIGNED_SHORT_4_4_4_4:
- extract4444(myswap_bytes,iter,extractComponents);
- for (k = 0; k < 4; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- extract4444rev(myswap_bytes,iter,extractComponents);
- for (k = 0; k < 4; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_UNSIGNED_SHORT_5_5_5_1:
- extract5551(myswap_bytes,iter,extractComponents);
- for (k = 0; k < 4; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- extract1555rev(myswap_bytes,iter,extractComponents);
- for (k = 0; k < 4; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_UNSIGNED_SHORT:
- case GL_SHORT:
- if (myswap_bytes) {
- widget.ub[0] = iter[1];
- widget.ub[1] = iter[0];
- } else {
- widget.ub[0] = iter[0];
- widget.ub[1] = iter[1];
- }
- if (type == GL_SHORT) {
- if (index_format) {
- *iter2++ = widget.s[0];
- } else {
- /* rough approx */
- *iter2++ = widget.s[0]*2;
- }
- } else {
- *iter2++ = widget.us[0];
- }
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- extract8888(myswap_bytes,iter,extractComponents);
- for (k = 0; k < 4; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- extract8888rev(myswap_bytes,iter,extractComponents);
- for (k = 0; k < 4; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_UNSIGNED_INT_10_10_10_2:
- extract1010102(myswap_bytes,iter,extractComponents);
- for (k = 0; k < 4; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- extract2101010rev(myswap_bytes,iter,extractComponents);
- for (k = 0; k < 4; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_INT:
- case GL_UNSIGNED_INT:
- case GL_FLOAT:
- if (myswap_bytes) {
- widget.ub[0] = iter[3];
- widget.ub[1] = iter[2];
- widget.ub[2] = iter[1];
- widget.ub[3] = iter[0];
- } else {
- widget.ub[0] = iter[0];
- widget.ub[1] = iter[1];
- widget.ub[2] = iter[2];
- widget.ub[3] = iter[3];
- }
- if (type == GL_FLOAT) {
- if (index_format) {
- *iter2++ = widget.f;
- } else {
- *iter2++ = 65535 * widget.f;
- }
- } else if (type == GL_UNSIGNED_INT) {
- if (index_format) {
- *iter2++ = widget.ui;
- } else {
- *iter2++ = widget.ui >> 16;
- }
- } else {
- if (index_format) {
- *iter2++ = widget.i;
- } else {
- *iter2++ = widget.i >> 15;
- }
- }
- break;
- }
- iter += element_size;
- } /* for j */
- start += rowsize;
-#if 1
- /* want 'iter' pointing at start, not within, row for assertion
- * purposes
- */
- iter= start;
-#endif
- } /* for i */
-
- /* iterators should be one byte past end */
- if (!isTypePackedPixel(type)) {
- assert(iter2 == &newimage[width*height*components]);
- }
- else {
- assert(iter2 == &newimage[width*height*
- elements_per_group(format,0)]);
- }
- assert( iter == &((const GLubyte *)userdata)[rowsize*height +
- psm->unpack_skip_rows * rowsize +
- psm->unpack_skip_pixels * group_size] );
-
- } /* else */
-} /* fill_image() */
-
-/*
-** Insert array into user's data applying all pixel store modes.
-** The internal format is an array of unsigned shorts.
-** empty_image() because it is the opposite of fill_image().
-*/
-static void empty_image(const PixelStorageModes *psm,
- GLint width, GLint height, GLenum format,
- GLenum type, GLboolean index_format,
- const GLushort *oldimage, void *userdata)
-{
- GLint components;
- GLint element_size;
- GLint rowsize;
- GLint padding;
- GLint groups_per_line;
- GLint group_size;
- GLint elements_per_line;
- GLubyte *start;
- GLubyte *iter;
- const GLushort *iter2;
- GLint i, j, k;
- GLint myswap_bytes;
-
- myswap_bytes = psm->pack_swap_bytes;
- components = elements_per_group(format,type);
- if (psm->pack_row_length > 0) {
- groups_per_line = psm->pack_row_length;
- } else {
- groups_per_line = width;
- }
-
- /* All formats except GL_BITMAP fall out trivially */
- if (type == GL_BITMAP) {
- GLint bit_offset;
- GLint current_bit;
-
- rowsize = (groups_per_line * components + 7) / 8;
- padding = (rowsize % psm->pack_alignment);
- if (padding) {
- rowsize += psm->pack_alignment - padding;
- }
- start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize +
- (psm->pack_skip_pixels * components / 8);
- elements_per_line = width * components;
- iter2 = oldimage;
- for (i = 0; i < height; i++) {
- iter = start;
- bit_offset = (psm->pack_skip_pixels * components) % 8;
- for (j = 0; j < elements_per_line; j++) {
- if (index_format) {
- current_bit = iter2[0] & 1;
- } else {
- if (iter2[0] > 32767) {
- current_bit = 1;
- } else {
- current_bit = 0;
- }
- }
-
- if (current_bit) {
- if (psm->pack_lsb_first) {
- *iter |= (1 << bit_offset);
- } else {
- *iter |= (1 << (7 - bit_offset));
- }
- } else {
- if (psm->pack_lsb_first) {
- *iter &= ~(1 << bit_offset);
- } else {
- *iter &= ~(1 << (7 - bit_offset));
- }
- }
-
- bit_offset++;
- if (bit_offset == 8) {
- bit_offset = 0;
- iter++;
- }
- iter2++;
- }
- start += rowsize;
- }
- } else {
- float shoveComponents[4];
-
- element_size = bytes_per_element(type);
- group_size = element_size * components;
- if (element_size == 1) myswap_bytes = 0;
-
- rowsize = groups_per_line * group_size;
- padding = (rowsize % psm->pack_alignment);
- if (padding) {
- rowsize += psm->pack_alignment - padding;
- }
- start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize +
- psm->pack_skip_pixels * group_size;
- elements_per_line = width * components;
-
- iter2 = oldimage;
- for (i = 0; i < height; i++) {
- iter = start;
- for (j = 0; j < elements_per_line; j++) {
- Type_Widget widget;
-
- switch(type) {
- case GL_UNSIGNED_BYTE_3_3_2:
- for (k = 0; k < 3; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove332(shoveComponents,0,(void *)iter);
- break;
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- for (k = 0; k < 3; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove233rev(shoveComponents,0,(void *)iter);
- break;
- case GL_UNSIGNED_BYTE:
- if (index_format) {
- *iter = *iter2++;
- } else {
- *iter = *iter2++ >> 8;
- }
- break;
- case GL_BYTE:
- if (index_format) {
- *((GLbyte *) iter) = *iter2++;
- } else {
- *((GLbyte *) iter) = *iter2++ >> 9;
- }
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- for (k = 0; k < 3; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove565(shoveComponents,0,(void *)&widget.us[0]);
- if (myswap_bytes) {
- iter[0] = widget.ub[1];
- iter[1] = widget.ub[0];
- }
- else {
- *(GLushort *)iter = widget.us[0];
- }
- break;
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- for (k = 0; k < 3; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove565rev(shoveComponents,0,(void *)&widget.us[0]);
- if (myswap_bytes) {
- iter[0] = widget.ub[1];
- iter[1] = widget.ub[0];
- }
- else {
- *(GLushort *)iter = widget.us[0];
- }
- break;
- case GL_UNSIGNED_SHORT_4_4_4_4:
- for (k = 0; k < 4; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove4444(shoveComponents,0,(void *)&widget.us[0]);
- if (myswap_bytes) {
- iter[0] = widget.ub[1];
- iter[1] = widget.ub[0];
- } else {
- *(GLushort *)iter = widget.us[0];
- }
- break;
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- for (k = 0; k < 4; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove4444rev(shoveComponents,0,(void *)&widget.us[0]);
- if (myswap_bytes) {
- iter[0] = widget.ub[1];
- iter[1] = widget.ub[0];
- } else {
- *(GLushort *)iter = widget.us[0];
- }
- break;
- case GL_UNSIGNED_SHORT_5_5_5_1:
- for (k = 0; k < 4; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove5551(shoveComponents,0,(void *)&widget.us[0]);
- if (myswap_bytes) {
- iter[0] = widget.ub[1];
- iter[1] = widget.ub[0];
- } else {
- *(GLushort *)iter = widget.us[0];
- }
- break;
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- for (k = 0; k < 4; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove1555rev(shoveComponents,0,(void *)&widget.us[0]);
- if (myswap_bytes) {
- iter[0] = widget.ub[1];
- iter[1] = widget.ub[0];
- } else {
- *(GLushort *)iter = widget.us[0];
- }
- break;
- case GL_UNSIGNED_SHORT:
- case GL_SHORT:
- if (type == GL_SHORT) {
- if (index_format) {
- widget.s[0] = *iter2++;
- } else {
- widget.s[0] = *iter2++ >> 1;
- }
- } else {
- widget.us[0] = *iter2++;
- }
- if (myswap_bytes) {
- iter[0] = widget.ub[1];
- iter[1] = widget.ub[0];
- } else {
- iter[0] = widget.ub[0];
- iter[1] = widget.ub[1];
- }
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- for (k = 0; k < 4; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove8888(shoveComponents,0,(void *)&widget.ui);
- if (myswap_bytes) {
- iter[3] = widget.ub[0];
- iter[2] = widget.ub[1];
- iter[1] = widget.ub[2];
- iter[0] = widget.ub[3];
- } else {
- *(GLuint *)iter= widget.ui;
- }
-
- break;
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- for (k = 0; k < 4; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove8888rev(shoveComponents,0,(void *)&widget.ui);
- if (myswap_bytes) {
- iter[3] = widget.ub[0];
- iter[2] = widget.ub[1];
- iter[1] = widget.ub[2];
- iter[0] = widget.ub[3];
- } else {
- *(GLuint *)iter= widget.ui;
- }
- break;
- case GL_UNSIGNED_INT_10_10_10_2:
- for (k = 0; k < 4; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove1010102(shoveComponents,0,(void *)&widget.ui);
- if (myswap_bytes) {
- iter[3] = widget.ub[0];
- iter[2] = widget.ub[1];
- iter[1] = widget.ub[2];
- iter[0] = widget.ub[3];
- } else {
- *(GLuint *)iter= widget.ui;
- }
- break;
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- for (k = 0; k < 4; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove2101010rev(shoveComponents,0,(void *)&widget.ui);
- if (myswap_bytes) {
- iter[3] = widget.ub[0];
- iter[2] = widget.ub[1];
- iter[1] = widget.ub[2];
- iter[0] = widget.ub[3];
- } else {
- *(GLuint *)iter= widget.ui;
- }
- break;
- case GL_INT:
- case GL_UNSIGNED_INT:
- case GL_FLOAT:
- if (type == GL_FLOAT) {
- if (index_format) {
- widget.f = *iter2++;
- } else {
- widget.f = *iter2++ / (float) 65535.0;
- }
- } else if (type == GL_UNSIGNED_INT) {
- if (index_format) {
- widget.ui = *iter2++;
- } else {
- widget.ui = (unsigned int) *iter2++ * 65537;
- }
- } else {
- if (index_format) {
- widget.i = *iter2++;
- } else {
- widget.i = ((unsigned int) *iter2++ * 65537)/2;
- }
- }
- if (myswap_bytes) {
- iter[3] = widget.ub[0];
- iter[2] = widget.ub[1];
- iter[1] = widget.ub[2];
- iter[0] = widget.ub[3];
- } else {
- iter[0] = widget.ub[0];
- iter[1] = widget.ub[1];
- iter[2] = widget.ub[2];
- iter[3] = widget.ub[3];
- }
- break;
- }
- iter += element_size;
- } /* for j */
- start += rowsize;
-#if 1
- /* want 'iter' pointing at start, not within, row for assertion
- * purposes
- */
- iter= start;
-#endif
- } /* for i */
-
- /* iterators should be one byte past end */
- if (!isTypePackedPixel(type)) {
- assert(iter2 == &oldimage[width*height*components]);
- }
- else {
- assert(iter2 == &oldimage[width*height*
- elements_per_group(format,0)]);
- }
- assert( iter == &((GLubyte *)userdata)[rowsize*height +
- psm->pack_skip_rows * rowsize +
- psm->pack_skip_pixels * group_size] );
-
- } /* else */
-} /* empty_image() */
-
-/*--------------------------------------------------------------------------
- * Decimation of packed pixel types
- *--------------------------------------------------------------------------
- */
-static void extract332(int isSwap,
- const void *packedPixel, GLfloat extractComponents[])
-{
- GLubyte ubyte= *(const GLubyte *)packedPixel;
-
- isSwap= isSwap; /* turn off warnings */
-
- /* 11100000 == 0xe0 */
- /* 00011100 == 0x1c */
- /* 00000011 == 0x03 */
-
- extractComponents[0]= (float)((ubyte & 0xe0) >> 5) / 7.0;
- extractComponents[1]= (float)((ubyte & 0x1c) >> 2) / 7.0; /* 7 = 2^3-1 */
- extractComponents[2]= (float)((ubyte & 0x03) ) / 3.0; /* 3 = 2^2-1 */
-} /* extract332() */
-
-static void shove332(const GLfloat shoveComponents[],
- int index, void *packedPixel)
-{
- /* 11100000 == 0xe0 */
- /* 00011100 == 0x1c */
- /* 00000011 == 0x03 */
-
- assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
- assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
- assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
-
- /* due to limited precision, need to round before shoving */
- ((GLubyte *)packedPixel)[index] =
- ((GLubyte)((shoveComponents[0] * 7)+0.5) << 5) & 0xe0;
- ((GLubyte *)packedPixel)[index] |=
- ((GLubyte)((shoveComponents[1] * 7)+0.5) << 2) & 0x1c;
- ((GLubyte *)packedPixel)[index] |=
- ((GLubyte)((shoveComponents[2] * 3)+0.5) ) & 0x03;
-} /* shove332() */
-
-static void extract233rev(int isSwap,
- const void *packedPixel, GLfloat extractComponents[])
-{
- GLubyte ubyte= *(const GLubyte *)packedPixel;
-
- isSwap= isSwap; /* turn off warnings */
-
- /* 0000,0111 == 0x07 */
- /* 0011,1000 == 0x38 */
- /* 1100,0000 == 0xC0 */
-
- extractComponents[0]= (float)((ubyte & 0x07) ) / 7.0;
- extractComponents[1]= (float)((ubyte & 0x38) >> 3) / 7.0;
- extractComponents[2]= (float)((ubyte & 0xC0) >> 6) / 3.0;
-} /* extract233rev() */
-
-static void shove233rev(const GLfloat shoveComponents[],
- int index, void *packedPixel)
-{
- /* 0000,0111 == 0x07 */
- /* 0011,1000 == 0x38 */
- /* 1100,0000 == 0xC0 */
-
- assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
- assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
- assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
-
- /* due to limited precision, need to round before shoving */
- ((GLubyte *)packedPixel)[index] =
- ((GLubyte)((shoveComponents[0] * 7.0)+0.5) ) & 0x07;
- ((GLubyte *)packedPixel)[index]|=
- ((GLubyte)((shoveComponents[1] * 7.0)+0.5) << 3) & 0x38;
- ((GLubyte *)packedPixel)[index]|=
- ((GLubyte)((shoveComponents[2] * 3.0)+0.5) << 6) & 0xC0;
-} /* shove233rev() */
-
-static void extract565(int isSwap,
- const void *packedPixel, GLfloat extractComponents[])
-{
- GLushort ushort;
-
- if (isSwap) {
- ushort= __GLU_SWAP_2_BYTES(packedPixel);
- }
- else {
- ushort= *(const GLushort *)packedPixel;
- }
-
- /* 11111000,00000000 == 0xf800 */
- /* 00000111,11100000 == 0x07e0 */
- /* 00000000,00011111 == 0x001f */
-
- extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
- extractComponents[1]=(float)((ushort & 0x07e0) >> 5) / 63.0;/* 63 = 2^6-1*/
- extractComponents[2]=(float)((ushort & 0x001f) ) / 31.0;
-} /* extract565() */
-
-static void shove565(const GLfloat shoveComponents[],
- int index,void *packedPixel)
-{
- /* 11111000,00000000 == 0xf800 */
- /* 00000111,11100000 == 0x07e0 */
- /* 00000000,00011111 == 0x001f */
-
- assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
- assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
- assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
-
- /* due to limited precision, need to round before shoving */
- ((GLushort *)packedPixel)[index] =
- ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800;
- ((GLushort *)packedPixel)[index]|=
- ((GLushort)((shoveComponents[1] * 63)+0.5) << 5) & 0x07e0;
- ((GLushort *)packedPixel)[index]|=
- ((GLushort)((shoveComponents[2] * 31)+0.5) ) & 0x001f;
-} /* shove565() */
-
-static void extract565rev(int isSwap,
- const void *packedPixel, GLfloat extractComponents[])
-{
- GLushort ushort;
-
- if (isSwap) {
- ushort= __GLU_SWAP_2_BYTES(packedPixel);
- }
- else {
- ushort= *(const GLushort *)packedPixel;
- }
-
- /* 00000000,00011111 == 0x001f */
- /* 00000111,11100000 == 0x07e0 */
- /* 11111000,00000000 == 0xf800 */
-
- extractComponents[0]= (float)((ushort & 0x001F) ) / 31.0;
- extractComponents[1]= (float)((ushort & 0x07E0) >> 5) / 63.0;
- extractComponents[2]= (float)((ushort & 0xF800) >> 11) / 31.0;
-} /* extract565rev() */
-
-static void shove565rev(const GLfloat shoveComponents[],
- int index,void *packedPixel)
-{
- /* 00000000,00011111 == 0x001f */
- /* 00000111,11100000 == 0x07e0 */
- /* 11111000,00000000 == 0xf800 */
-
- assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
- assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
- assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
-
- /* due to limited precision, need to round before shoving */
- ((GLushort *)packedPixel)[index] =
- ((GLushort)((shoveComponents[0] * 31.0)+0.5) ) & 0x001F;
- ((GLushort *)packedPixel)[index]|=
- ((GLushort)((shoveComponents[1] * 63.0)+0.5) << 5) & 0x07E0;
- ((GLushort *)packedPixel)[index]|=
- ((GLushort)((shoveComponents[2] * 31.0)+0.5) << 11) & 0xF800;
-} /* shove565rev() */
-
-static void extract4444(int isSwap,const void *packedPixel,
- GLfloat extractComponents[])
-{
- GLushort ushort;
-
- if (isSwap) {
- ushort= __GLU_SWAP_2_BYTES(packedPixel);
- }
- else {
- ushort= *(const GLushort *)packedPixel;
- }
-
- /* 11110000,00000000 == 0xf000 */
- /* 00001111,00000000 == 0x0f00 */
- /* 00000000,11110000 == 0x00f0 */
- /* 00000000,00001111 == 0x000f */
-
- extractComponents[0]= (float)((ushort & 0xf000) >> 12) / 15.0;/* 15=2^4-1 */
- extractComponents[1]= (float)((ushort & 0x0f00) >> 8) / 15.0;
- extractComponents[2]= (float)((ushort & 0x00f0) >> 4) / 15.0;
- extractComponents[3]= (float)((ushort & 0x000f) ) / 15.0;
-} /* extract4444() */
-
-static void shove4444(const GLfloat shoveComponents[],
- int index,void *packedPixel)
-{
- assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
- assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
- assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
- assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
-
- /* due to limited precision, need to round before shoving */
- ((GLushort *)packedPixel)[index] =
- ((GLushort)((shoveComponents[0] * 15)+0.5) << 12) & 0xf000;
- ((GLushort *)packedPixel)[index]|=
- ((GLushort)((shoveComponents[1] * 15)+0.5) << 8) & 0x0f00;
- ((GLushort *)packedPixel)[index]|=
- ((GLushort)((shoveComponents[2] * 15)+0.5) << 4) & 0x00f0;
- ((GLushort *)packedPixel)[index]|=
- ((GLushort)((shoveComponents[3] * 15)+0.5) ) & 0x000f;
-} /* shove4444() */
-
-static void extract4444rev(int isSwap,const void *packedPixel,
- GLfloat extractComponents[])
-{
- GLushort ushort;
-
- if (isSwap) {
- ushort= __GLU_SWAP_2_BYTES(packedPixel);
- }
- else {
- ushort= *(const GLushort *)packedPixel;
- }
-
- /* 00000000,00001111 == 0x000f */
- /* 00000000,11110000 == 0x00f0 */
- /* 00001111,00000000 == 0x0f00 */
- /* 11110000,00000000 == 0xf000 */
-
- /* 15 = 2^4-1 */
- extractComponents[0]= (float)((ushort & 0x000F) ) / 15.0;
- extractComponents[1]= (float)((ushort & 0x00F0) >> 4) / 15.0;
- extractComponents[2]= (float)((ushort & 0x0F00) >> 8) / 15.0;
- extractComponents[3]= (float)((ushort & 0xF000) >> 12) / 15.0;
-} /* extract4444rev() */
-
-static void shove4444rev(const GLfloat shoveComponents[],
- int index,void *packedPixel)
-{
- /* 00000000,00001111 == 0x000f */
- /* 00000000,11110000 == 0x00f0 */
- /* 00001111,00000000 == 0x0f00 */
- /* 11110000,00000000 == 0xf000 */
-
- assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
- assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
- assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
- assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
-
- /* due to limited precision, need to round before shoving */
- ((GLushort *)packedPixel)[index] =
- ((GLushort)((shoveComponents[0] * 15)+0.5) ) & 0x000F;
- ((GLushort *)packedPixel)[index]|=
- ((GLushort)((shoveComponents[1] * 15)+0.5) << 4) & 0x00F0;
- ((GLushort *)packedPixel)[index]|=
- ((GLushort)((shoveComponents[2] * 15)+0.5) << 8) & 0x0F00;
- ((GLushort *)packedPixel)[index]|=
- ((GLushort)((shoveComponents[3] * 15)+0.5) << 12) & 0xF000;
-} /* shove4444rev() */
-
-static void extract5551(int isSwap,const void *packedPixel,
- GLfloat extractComponents[])
-{
- GLushort ushort;
-
- if (isSwap) {
- ushort= __GLU_SWAP_2_BYTES(packedPixel);
- }
- else {
- ushort= *(const GLushort *)packedPixel;
- }
-
- /* 11111000,00000000 == 0xf800 */
- /* 00000111,11000000 == 0x07c0 */
- /* 00000000,00111110 == 0x003e */
- /* 00000000,00000001 == 0x0001 */
-
- extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/
- extractComponents[1]=(float)((ushort & 0x07c0) >> 6) / 31.0;
- extractComponents[2]=(float)((ushort & 0x003e) >> 1) / 31.0;
- extractComponents[3]=(float)((ushort & 0x0001) );
-} /* extract5551() */
-
-static void shove5551(const GLfloat shoveComponents[],
- int index,void *packedPixel)
-{
- /* 11111000,00000000 == 0xf800 */
- /* 00000111,11000000 == 0x07c0 */
- /* 00000000,00111110 == 0x003e */
- /* 00000000,00000001 == 0x0001 */
-
- assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
- assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
- assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
- assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
-
- /* due to limited precision, need to round before shoving */
- ((GLushort *)packedPixel)[index] =
- ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800;
- ((GLushort *)packedPixel)[index]|=
- ((GLushort)((shoveComponents[1] * 31)+0.5) << 6) & 0x07c0;
- ((GLushort *)packedPixel)[index]|=
- ((GLushort)((shoveComponents[2] * 31)+0.5) << 1) & 0x003e;
- ((GLushort *)packedPixel)[index]|=
- ((GLushort)((shoveComponents[3])+0.5) ) & 0x0001;
-} /* shove5551() */
-
-static void extract1555rev(int isSwap,const void *packedPixel,
- GLfloat extractComponents[])
-{
- GLushort ushort;
-
- if (isSwap) {
- ushort= __GLU_SWAP_2_BYTES(packedPixel);
- }
- else {
- ushort= *(const GLushort *)packedPixel;
- }
-
- /* 00000000,00011111 == 0x001F */
- /* 00000011,11100000 == 0x03E0 */
- /* 01111100,00000000 == 0x7C00 */
- /* 10000000,00000000 == 0x8000 */
-
- /* 31 = 2^5-1 */
- extractComponents[0]= (float)((ushort & 0x001F) ) / 31.0;
- extractComponents[1]= (float)((ushort & 0x03E0) >> 5) / 31.0;
- extractComponents[2]= (float)((ushort & 0x7C00) >> 10) / 31.0;
- extractComponents[3]= (float)((ushort & 0x8000) >> 15);
-} /* extract1555rev() */
-
-static void shove1555rev(const GLfloat shoveComponents[],
- int index,void *packedPixel)
-{
- /* 00000000,00011111 == 0x001F */
- /* 00000011,11100000 == 0x03E0 */
- /* 01111100,00000000 == 0x7C00 */
- /* 10000000,00000000 == 0x8000 */
-
- assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
- assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
- assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
- assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
-
- /* due to limited precision, need to round before shoving */
- ((GLushort *)packedPixel)[index] =
- ((GLushort)((shoveComponents[0] * 31)+0.5) ) & 0x001F;
- ((GLushort *)packedPixel)[index]|=
- ((GLushort)((shoveComponents[1] * 31)+0.5) << 5) & 0x03E0;
- ((GLushort *)packedPixel)[index]|=
- ((GLushort)((shoveComponents[2] * 31)+0.5) << 10) & 0x7C00;
- ((GLushort *)packedPixel)[index]|=
- ((GLushort)((shoveComponents[3])+0.5) << 15) & 0x8000;
-} /* shove1555rev() */
-
-static void extract8888(int isSwap,
- const void *packedPixel, GLfloat extractComponents[])
-{
- GLuint uint;
-
- if (isSwap) {
- uint= __GLU_SWAP_4_BYTES(packedPixel);
- }
- else {
- uint= *(const GLuint *)packedPixel;
- }
-
- /* 11111111,00000000,00000000,00000000 == 0xff000000 */
- /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
- /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
- /* 00000000,00000000,00000000,11111111 == 0x000000ff */
-
- /* 255 = 2^8-1 */
- extractComponents[0]= (float)((uint & 0xff000000) >> 24) / 255.0;
- extractComponents[1]= (float)((uint & 0x00ff0000) >> 16) / 255.0;
- extractComponents[2]= (float)((uint & 0x0000ff00) >> 8) / 255.0;
- extractComponents[3]= (float)((uint & 0x000000ff) ) / 255.0;
-} /* extract8888() */
-
-static void shove8888(const GLfloat shoveComponents[],
- int index,void *packedPixel)
-{
- /* 11111111,00000000,00000000,00000000 == 0xff000000 */
- /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
- /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
- /* 00000000,00000000,00000000,11111111 == 0x000000ff */
-
- assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
- assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
- assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
- assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
-
- /* due to limited precision, need to round before shoving */
- ((GLuint *)packedPixel)[index] =
- ((GLuint)((shoveComponents[0] * 255)+0.5) << 24) & 0xff000000;
- ((GLuint *)packedPixel)[index]|=
- ((GLuint)((shoveComponents[1] * 255)+0.5) << 16) & 0x00ff0000;
- ((GLuint *)packedPixel)[index]|=
- ((GLuint)((shoveComponents[2] * 255)+0.5) << 8) & 0x0000ff00;
- ((GLuint *)packedPixel)[index]|=
- ((GLuint)((shoveComponents[3] * 255)+0.5) ) & 0x000000ff;
-} /* shove8888() */
-
-static void extract8888rev(int isSwap,
- const void *packedPixel,GLfloat extractComponents[])
-{
- GLuint uint;
-
- if (isSwap) {
- uint= __GLU_SWAP_4_BYTES(packedPixel);
- }
- else {
- uint= *(const GLuint *)packedPixel;
- }
-
- /* 00000000,00000000,00000000,11111111 == 0x000000ff */
- /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
- /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
- /* 11111111,00000000,00000000,00000000 == 0xff000000 */
-
- /* 255 = 2^8-1 */
- extractComponents[0]= (float)((uint & 0x000000FF) ) / 255.0;
- extractComponents[1]= (float)((uint & 0x0000FF00) >> 8) / 255.0;
- extractComponents[2]= (float)((uint & 0x00FF0000) >> 16) / 255.0;
- extractComponents[3]= (float)((uint & 0xFF000000) >> 24) / 255.0;
-} /* extract8888rev() */
-
-static void shove8888rev(const GLfloat shoveComponents[],
- int index,void *packedPixel)
-{
- /* 00000000,00000000,00000000,11111111 == 0x000000ff */
- /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */
- /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */
- /* 11111111,00000000,00000000,00000000 == 0xff000000 */
-
- assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
- assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
- assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
- assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
-
- /* due to limited precision, need to round before shoving */
- ((GLuint *)packedPixel)[index] =
- ((GLuint)((shoveComponents[0] * 255)+0.5) ) & 0x000000FF;
- ((GLuint *)packedPixel)[index]|=
- ((GLuint)((shoveComponents[1] * 255)+0.5) << 8) & 0x0000FF00;
- ((GLuint *)packedPixel)[index]|=
- ((GLuint)((shoveComponents[2] * 255)+0.5) << 16) & 0x00FF0000;
- ((GLuint *)packedPixel)[index]|=
- ((GLuint)((shoveComponents[3] * 255)+0.5) << 24) & 0xFF000000;
-} /* shove8888rev() */
-
-static void extract1010102(int isSwap,
- const void *packedPixel,GLfloat extractComponents[])
-{
- GLuint uint;
-
- if (isSwap) {
- uint= __GLU_SWAP_4_BYTES(packedPixel);
- }
- else {
- uint= *(const GLuint *)packedPixel;
- }
-
- /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
- /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
- /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
- /* 00000000,00000000,00000000,00000011 == 0x00000003 */
-
- /* 1023 = 2^10-1 */
- extractComponents[0]= (float)((uint & 0xffc00000) >> 22) / 1023.0;
- extractComponents[1]= (float)((uint & 0x003ff000) >> 12) / 1023.0;
- extractComponents[2]= (float)((uint & 0x00000ffc) >> 2) / 1023.0;
- extractComponents[3]= (float)((uint & 0x00000003) ) / 3.0;
-} /* extract1010102() */
-
-static void shove1010102(const GLfloat shoveComponents[],
- int index,void *packedPixel)
-{
- /* 11111111,11000000,00000000,00000000 == 0xffc00000 */
- /* 00000000,00111111,11110000,00000000 == 0x003ff000 */
- /* 00000000,00000000,00001111,11111100 == 0x00000ffc */
- /* 00000000,00000000,00000000,00000011 == 0x00000003 */
-
- assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
- assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
- assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
- assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
-
- /* due to limited precision, need to round before shoving */
- ((GLuint *)packedPixel)[index] =
- ((GLuint)((shoveComponents[0] * 1023)+0.5) << 22) & 0xffc00000;
- ((GLuint *)packedPixel)[index]|=
- ((GLuint)((shoveComponents[1] * 1023)+0.5) << 12) & 0x003ff000;
- ((GLuint *)packedPixel)[index]|=
- ((GLuint)((shoveComponents[2] * 1023)+0.5) << 2) & 0x00000ffc;
- ((GLuint *)packedPixel)[index]|=
- ((GLuint)((shoveComponents[3] * 3)+0.5) ) & 0x00000003;
-} /* shove1010102() */
-
-static void extract2101010rev(int isSwap,
- const void *packedPixel,
- GLfloat extractComponents[])
-{
- GLuint uint;
-
- if (isSwap) {
- uint= __GLU_SWAP_4_BYTES(packedPixel);
- }
- else {
- uint= *(const GLuint *)packedPixel;
- }
-
- /* 00000000,00000000,00000011,11111111 == 0x000003FF */
- /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
- /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
- /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
-
- /* 1023 = 2^10-1 */
- extractComponents[0]= (float)((uint & 0x000003FF) ) / 1023.0;
- extractComponents[1]= (float)((uint & 0x000FFC00) >> 10) / 1023.0;
- extractComponents[2]= (float)((uint & 0x3FF00000) >> 20) / 1023.0;
- extractComponents[3]= (float)((uint & 0xC0000000) >> 30) / 3.0;
- /* 3 = 2^2-1 */
-} /* extract2101010rev() */
-
-static void shove2101010rev(const GLfloat shoveComponents[],
- int index,void *packedPixel)
-{
- /* 00000000,00000000,00000011,11111111 == 0x000003FF */
- /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */
- /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */
- /* 11000000,00000000,00000000,00000000 == 0xC0000000 */
-
- assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0);
- assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0);
- assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0);
- assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0);
-
- /* due to limited precision, need to round before shoving */
- ((GLuint *)packedPixel)[index] =
- ((GLuint)((shoveComponents[0] * 1023)+0.5) ) & 0x000003FF;
- ((GLuint *)packedPixel)[index]|=
- ((GLuint)((shoveComponents[1] * 1023)+0.5) << 10) & 0x000FFC00;
- ((GLuint *)packedPixel)[index]|=
- ((GLuint)((shoveComponents[2] * 1023)+0.5) << 20) & 0x3FF00000;
- ((GLuint *)packedPixel)[index]|=
- ((GLuint)((shoveComponents[3] * 3)+0.5) << 30) & 0xC0000000;
-} /* shove2101010rev() */
-
-static void scaleInternalPackedPixel(int components,
- void (*extractPackedPixel)
- (int, const void *,GLfloat []),
- void (*shovePackedPixel)
- (const GLfloat [], int, void *),
- GLint widthIn,GLint heightIn,
- const void *dataIn,
- GLint widthOut,GLint heightOut,
- void *dataOut,
- GLint pixelSizeInBytes,
- GLint rowSizeInBytes,GLint isSwap)
-{
- float convx;
- float convy;
- float percent;
-
- /* Max components in a format is 4, so... */
- float totals[4];
- float extractTotals[4], extractMoreTotals[4], shoveTotals[4];
-
- float area;
- int i,j,k,xindex;
-
- const char *temp, *temp0;
- int outindex;
-
- int lowx_int, highx_int, lowy_int, highy_int;
- float x_percent, y_percent;
- float lowx_float, highx_float, lowy_float, highy_float;
- float convy_float, convx_float;
- int convy_int, convx_int;
- int l, m;
- const char *left, *right;
-
- if (widthIn == widthOut*2 && heightIn == heightOut*2) {
- halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel,
- widthIn, heightIn, dataIn, dataOut,
- pixelSizeInBytes,rowSizeInBytes,isSwap);
- return;
- }
- convy = (float) heightIn/heightOut;
- convx = (float) widthIn/widthOut;
- convy_int = floor(convy);
- convy_float = convy - convy_int;
- convx_int = floor(convx);
- convx_float = convx - convx_int;
-
- area = convx * convy;
-
- lowy_int = 0;
- lowy_float = 0;
- highy_int = convy_int;
- highy_float = convy_float;
-
- for (i = 0; i < heightOut; i++) {
- lowx_int = 0;
- lowx_float = 0;
- highx_int = convx_int;
- highx_float = convx_float;
-
- for (j = 0; j < widthOut; j++) {
- /*
- ** Ok, now apply box filter to box that goes from (lowx, lowy)
- ** to (highx, highy) on input data into this pixel on output
- ** data.
- */
- totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
-
- /* calculate the value for pixels in the 1st row */
- xindex = lowx_int*pixelSizeInBytes;
- if((highy_int>lowy_int) && (highx_int>lowx_int)) {
-
- y_percent = 1-lowy_float;
- temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes;
- percent = y_percent * (1-lowx_float);
-#if 0
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * percent;
- }
- }
-#else
- (*extractPackedPixel)(isSwap,temp,extractTotals);
- for (k = 0; k < components; k++) {
- totals[k]+= extractTotals[k] * percent;
- }
-#endif
- left = temp;
- for(l = lowx_int+1; l < highx_int; l++) {
- temp += pixelSizeInBytes;
-#if 0
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] +=
- __GLU_SWAP_2_BYTES(temp_index) * y_percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * y_percent;
- }
- }
-#else
- (*extractPackedPixel)(isSwap,temp,extractTotals);
- for (k = 0; k < components; k++) {
- totals[k]+= extractTotals[k] * y_percent;
- }
-#endif
- }
- temp += pixelSizeInBytes;
- right = temp;
- percent = y_percent * highx_float;
-#if 0
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * percent;
- }
- }
-#else
- (*extractPackedPixel)(isSwap,temp,extractTotals);
- for (k = 0; k < components; k++) {
- totals[k]+= extractTotals[k] * percent;
- }
-#endif
-
- /* calculate the value for pixels in the last row */
-
- y_percent = highy_float;
- percent = y_percent * (1-lowx_float);
- temp = (const char *)dataIn + xindex + highy_int * rowSizeInBytes;
-#if 0
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * percent;
- }
- }
-#else
- (*extractPackedPixel)(isSwap,temp,extractTotals);
- for (k = 0; k < components; k++) {
- totals[k]+= extractTotals[k] * percent;
- }
-#endif
- for(l = lowx_int+1; l < highx_int; l++) {
- temp += pixelSizeInBytes;
-#if 0
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] +=
- __GLU_SWAP_2_BYTES(temp_index) * y_percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * y_percent;
- }
- }
-#else
- (*extractPackedPixel)(isSwap,temp,extractTotals);
- for (k = 0; k < components; k++) {
- totals[k]+= extractTotals[k] * y_percent;
- }
-#endif
-
- }
- temp += pixelSizeInBytes;
- percent = y_percent * highx_float;
-#if 0
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * percent;
- }
- }
-#else
- (*extractPackedPixel)(isSwap,temp,extractTotals);
- for (k = 0; k < components; k++) {
- totals[k]+= extractTotals[k] * percent;
- }
-#endif
-
- /* calculate the value for pixels in the 1st and last column */
- for(m = lowy_int+1; m < highy_int; m++) {
- left += rowSizeInBytes;
- right += rowSizeInBytes;
-#if 0
- for (k = 0; k < components;
- k++, left += element_size, right += element_size) {
- if (myswap_bytes) {
- totals[k] +=
- __GLU_SWAP_2_BYTES(left) * (1-lowx_float) +
- __GLU_SWAP_2_BYTES(right) * highx_float;
- } else {
- totals[k] += *(const GLushort*)left * (1-lowx_float)
- + *(const GLushort*)right * highx_float;
- }
- }
-#else
- (*extractPackedPixel)(isSwap,left,extractTotals);
- (*extractPackedPixel)(isSwap,right,extractMoreTotals);
- for (k = 0; k < components; k++) {
- totals[k]+= (extractTotals[k]*(1-lowx_float) +
- extractMoreTotals[k]*highx_float);
- }
-#endif
- }
- } else if (highy_int > lowy_int) {
- x_percent = highx_float - lowx_float;
- percent = (1-lowy_float)*x_percent;
- temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes;
-#if 0
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * percent;
- }
- }
-#else
- (*extractPackedPixel)(isSwap,temp,extractTotals);
- for (k = 0; k < components; k++) {
- totals[k]+= extractTotals[k] * percent;
- }
-#endif
- for(m = lowy_int+1; m < highy_int; m++) {
- temp += rowSizeInBytes;
-#if 0
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] +=
- __GLU_SWAP_2_BYTES(temp_index) * x_percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * x_percent;
- }
- }
-#else
- (*extractPackedPixel)(isSwap,temp,extractTotals);
- for (k = 0; k < components; k++) {
- totals[k]+= extractTotals[k] * x_percent;
- }
-#endif
- }
- percent = x_percent * highy_float;
- temp += rowSizeInBytes;
-#if 0
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * percent;
- }
- }
-#else
- (*extractPackedPixel)(isSwap,temp,extractTotals);
- for (k = 0; k < components; k++) {
- totals[k]+= extractTotals[k] * percent;
- }
-#endif
- } else if (highx_int > lowx_int) {
- y_percent = highy_float - lowy_float;
- percent = (1-lowx_float)*y_percent;
- temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes;
-#if 0
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * percent;
- }
- }
-#else
- (*extractPackedPixel)(isSwap,temp,extractTotals);
- for (k = 0; k < components; k++) {
- totals[k]+= extractTotals[k] * percent;
- }
-#endif
- for (l = lowx_int+1; l < highx_int; l++) {
- temp += pixelSizeInBytes;
-#if 0
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] +=
- __GLU_SWAP_2_BYTES(temp_index) * y_percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * y_percent;
- }
- }
-#else
- (*extractPackedPixel)(isSwap,temp,extractTotals);
- for (k = 0; k < components; k++) {
- totals[k]+= extractTotals[k] * y_percent;
- }
-#endif
- }
- temp += pixelSizeInBytes;
- percent = y_percent * highx_float;
-#if 0
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * percent;
- }
- }
-#else
- (*extractPackedPixel)(isSwap,temp,extractTotals);
- for (k = 0; k < components; k++) {
- totals[k]+= extractTotals[k] * percent;
- }
-#endif
- } else {
- percent = (highy_float-lowy_float)*(highx_float-lowx_float);
- temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes;
-#if 0
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent;
- } else {
- totals[k] += *(const GLushort*)temp_index * percent;
- }
- }
-#else
- (*extractPackedPixel)(isSwap,temp,extractTotals);
- for (k = 0; k < components; k++) {
- totals[k]+= extractTotals[k] * percent;
- }
-#endif
- }
-
- /* this is for the pixels in the body */
- temp0 = (const char *)dataIn + xindex + pixelSizeInBytes + (lowy_int+1)*rowSizeInBytes;
- for (m = lowy_int+1; m < highy_int; m++) {
- temp = temp0;
- for(l = lowx_int+1; l < highx_int; l++) {
-#if 0
- for (k = 0, temp_index = temp; k < components;
- k++, temp_index += element_size) {
- if (myswap_bytes) {
- totals[k] += __GLU_SWAP_2_BYTES(temp_index);
- } else {
- totals[k] += *(const GLushort*)temp_index;
- }
- }
-#else
- (*extractPackedPixel)(isSwap,temp,extractTotals);
- for (k = 0; k < components; k++) {
- totals[k]+= extractTotals[k];
- }
-#endif
- temp += pixelSizeInBytes;
- }
- temp0 += rowSizeInBytes;
- }
-
- outindex = (j + (i * widthOut)); /* * (components == 1) */
-#if 0
- for (k = 0; k < components; k++) {
- dataout[outindex + k] = totals[k]/area;
- /*printf("totals[%d] = %f\n", k, totals[k]);*/
- }
-#else
- for (k = 0; k < components; k++) {
- shoveTotals[k]= totals[k]/area;
- }
- (*shovePackedPixel)(shoveTotals,outindex,(void *)dataOut);
-#endif
- lowx_int = highx_int;
- lowx_float = highx_float;
- highx_int += convx_int;
- highx_float += convx_float;
- if(highx_float > 1) {
- highx_float -= 1.0;
- highx_int++;
- }
- }
- lowy_int = highy_int;
- lowy_float = highy_float;
- highy_int += convy_int;
- highy_float += convy_float;
- if(highy_float > 1) {
- highy_float -= 1.0;
- highy_int++;
- }
- }
-
- assert(outindex == (widthOut*heightOut - 1));
-} /* scaleInternalPackedPixel() */
-
-/* rowSizeInBytes is at least the width (in bytes) due to padding on
- * inputs; not always equal. Output NEVER has row padding.
- */
-static void halveImagePackedPixel(int components,
- void (*extractPackedPixel)
- (int, const void *,GLfloat []),
- void (*shovePackedPixel)
- (const GLfloat [],int, void *),
- GLint width, GLint height,
- const void *dataIn, void *dataOut,
- GLint pixelSizeInBytes,
- GLint rowSizeInBytes, GLint isSwap)
-{
- /* handle case where there is only 1 column/row */
- if (width == 1 || height == 1) {
- assert(!(width == 1 && height == 1)); /* can't be 1x1 */
- halve1DimagePackedPixel(components,extractPackedPixel,shovePackedPixel,
- width,height,dataIn,dataOut,pixelSizeInBytes,
- rowSizeInBytes,isSwap);
- return;
- }
-
- {
- int ii, jj;
-
- int halfWidth= width / 2;
- int halfHeight= height / 2;
- const char *src= (const char *) dataIn;
- int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
- int outIndex= 0;
-
- for (ii= 0; ii< halfHeight; ii++) {
- for (jj= 0; jj< halfWidth; jj++) {
-#define BOX4 4
- float totals[4]; /* 4 is maximum components */
- float extractTotals[BOX4][4]; /* 4 is maximum components */
- int cc;
-
- (*extractPackedPixel)(isSwap,src,
- &extractTotals[0][0]);
- (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
- &extractTotals[1][0]);
- (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
- &extractTotals[2][0]);
- (*extractPackedPixel)(isSwap,
- (src+rowSizeInBytes+pixelSizeInBytes),
- &extractTotals[3][0]);
- for (cc = 0; cc < components; cc++) {
- int kk;
-
- /* grab 4 pixels to average */
- totals[cc]= 0.0;
- /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
- * extractTotals[2][RED]+extractTotals[3][RED];
- * totals[RED]/= 4.0;
- */
- for (kk = 0; kk < BOX4; kk++) {
- totals[cc]+= extractTotals[kk][cc];
- }
- totals[cc]/= (float)BOX4;
- }
- (*shovePackedPixel)(totals,outIndex,dataOut);
-
- outIndex++;
- /* skip over to next square of 4 */
- src+= pixelSizeInBytes + pixelSizeInBytes;
- }
- /* skip past pad bytes, if any, to get to next row */
- src+= padBytes;
-
- /* src is at beginning of a row here, but it's the second row of
- * the square block of 4 pixels that we just worked on so we
- * need to go one more row.
- * i.e.,
- * OO...
- * here -->OO...
- * but want -->OO...
- * OO...
- * ...
- */
- src+= rowSizeInBytes;
- }
-
- /* both pointers must reach one byte after the end */
- assert(src == &((const char *)dataIn)[rowSizeInBytes*height]);
- assert(outIndex == halfWidth * halfHeight);
- }
-} /* halveImagePackedPixel() */
-
-static void halve1DimagePackedPixel(int components,
- void (*extractPackedPixel)
- (int, const void *,GLfloat []),
- void (*shovePackedPixel)
- (const GLfloat [],int, void *),
- GLint width, GLint height,
- const void *dataIn, void *dataOut,
- GLint pixelSizeInBytes,
- GLint rowSizeInBytes, GLint isSwap)
-{
- int halfWidth= width / 2;
- int halfHeight= height / 2;
- const char *src= (const char *) dataIn;
- int jj;
-
- assert(width == 1 || height == 1); /* must be 1D */
- assert(width != height); /* can't be square */
-
- if (height == 1) { /* 1 row */
- int outIndex= 0;
-
- assert(width != 1); /* widthxheight can't be 1x1 */
- halfHeight= 1;
-
- /* one horizontal row with possible pad bytes */
-
- for (jj= 0; jj< halfWidth; jj++) {
-#define BOX2 2
- float totals[4]; /* 4 is maximum components */
- float extractTotals[BOX2][4]; /* 4 is maximum components */
- int cc;
-
- /* average two at a time, instead of four */
- (*extractPackedPixel)(isSwap,src,
- &extractTotals[0][0]);
- (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
- &extractTotals[1][0]);
- for (cc = 0; cc < components; cc++) {
- int kk;
-
- /* grab 2 pixels to average */
- totals[cc]= 0.0;
- /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
- * totals[RED]/= 2.0;
- */
- for (kk = 0; kk < BOX2; kk++) {
- totals[cc]+= extractTotals[kk][cc];
- }
- totals[cc]/= (float)BOX2;
- }
- (*shovePackedPixel)(totals,outIndex,dataOut);
-
- outIndex++;
- /* skip over to next group of 2 */
- src+= pixelSizeInBytes + pixelSizeInBytes;
- }
-
- {
- int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
- src+= padBytes; /* for assertion only */
- }
- assert(src == &((const char *)dataIn)[rowSizeInBytes]);
- assert(outIndex == halfWidth * halfHeight);
- }
- else if (width == 1) { /* 1 column */
- int outIndex= 0;
-
- assert(height != 1); /* widthxheight can't be 1x1 */
- halfWidth= 1;
- /* one vertical column with possible pad bytes per row */
- /* average two at a time */
-
- for (jj= 0; jj< halfHeight; jj++) {
-#define BOX2 2
- float totals[4]; /* 4 is maximum components */
- float extractTotals[BOX2][4]; /* 4 is maximum components */
- int cc;
-
- /* average two at a time, instead of four */
- (*extractPackedPixel)(isSwap,src,
- &extractTotals[0][0]);
- (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
- &extractTotals[1][0]);
- for (cc = 0; cc < components; cc++) {
- int kk;
-
- /* grab 2 pixels to average */
- totals[cc]= 0.0;
- /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
- * totals[RED]/= 2.0;
- */
- for (kk = 0; kk < BOX2; kk++) {
- totals[cc]+= extractTotals[kk][cc];
- }
- totals[cc]/= (float)BOX2;
- }
- (*shovePackedPixel)(totals,outIndex,dataOut);
-
- outIndex++;
- src+= rowSizeInBytes + rowSizeInBytes; /* go to row after next */
- }
-
- assert(src == &((const char *)dataIn)[rowSizeInBytes*height]);
- assert(outIndex == halfWidth * halfHeight);
- }
-} /* halve1DimagePackedPixel() */
-
-/*===========================================================================*/
-
-#ifdef RESOLVE_3D_TEXTURE_SUPPORT
-/*
- * This section ensures that GLU 1.3 will load and run on
- * a GL 1.1 implementation. It dynamically resolves the
- * call to glTexImage3D() which might not be available.
- * Or is it might be supported as an extension.
- * Contributed by Gerk Huisma <gerk@five-d.demon.nl>.
- */
-
-typedef void (GLAPIENTRY *TexImage3Dproc)( GLenum target, GLint level,
- GLenum internalFormat,
- GLsizei width, GLsizei height,
- GLsizei depth, GLint border,
- GLenum format, GLenum type,
- const GLvoid *pixels );
-
-static TexImage3Dproc pTexImage3D = 0;
-
-#if !defined(_WIN32) && !defined(__WIN32__)
-# include <dlfcn.h>
-# include <sys/types.h>
-#else
- WINGDIAPI PROC WINAPI wglGetProcAddress(LPCSTR);
-#endif
-
-static void gluTexImage3D( GLenum target, GLint level,
- GLenum internalFormat,
- GLsizei width, GLsizei height,
- GLsizei depth, GLint border,
- GLenum format, GLenum type,
- const GLvoid *pixels )
-{
- if (!pTexImage3D) {
-#if defined(_WIN32) || defined(__WIN32__)
- pTexImage3D = (TexImage3Dproc) wglGetProcAddress("glTexImage3D");
- if (!pTexImage3D)
- pTexImage3D = (TexImage3Dproc) wglGetProcAddress("glTexImage3DEXT");
-#else
- void *libHandle = dlopen("libgl.so", RTLD_LAZY);
- pTexImage3D = (TexImage3Dproc) dlsym(libHandle, "glTexImage3D" );
- if (!pTexImage3D)
- pTexImage3D = (TexImage3Dproc) dlsym(libHandle,"glTexImage3DEXT");
- dlclose(libHandle);
-#endif
- }
-
- /* Now call glTexImage3D */
- if (pTexImage3D)
- pTexImage3D(target, level, internalFormat, width, height,
- depth, border, format, type, pixels);
-}
-
-#else
-
-/* Only bind to a GL 1.2 implementation: */
-#define gluTexImage3D glTexImage3D
-
-#endif
-
-static GLint imageSize3D(GLint width, GLint height, GLint depth,
- GLenum format, GLenum type)
-{
- int components= elements_per_group(format,type);
- int bytes_per_row= bytes_per_element(type) * width;
-
-assert(width > 0 && height > 0 && depth > 0);
-assert(type != GL_BITMAP);
-
- return bytes_per_row * height * depth * components;
-} /* imageSize3D() */
-
-static void fillImage3D(const PixelStorageModes *psm,
- GLint width, GLint height, GLint depth, GLenum format,
- GLenum type, GLboolean indexFormat,
- const void *userImage, GLushort *newImage)
-{
- int myswapBytes;
- int components;
- int groupsPerLine;
- int elementSize;
- int groupSize;
- int rowSize;
- int padding;
- int elementsPerLine;
- int rowsPerImage;
- int imageSize;
- const GLubyte *start, *rowStart, *iter;
- GLushort *iter2;
- int ww, hh, dd, k;
-
- myswapBytes= psm->unpack_swap_bytes;
- components= elements_per_group(format,type);
- if (psm->unpack_row_length > 0) {
- groupsPerLine= psm->unpack_row_length;
- }
- else {
- groupsPerLine= width;
- }
- elementSize= bytes_per_element(type);
- groupSize= elementSize * components;
- if (elementSize == 1) myswapBytes= 0;
-
- /* 3dstuff begin */
- if (psm->unpack_image_height > 0) {
- rowsPerImage= psm->unpack_image_height;
- }
- else {
- rowsPerImage= height;
- }
- /* 3dstuff end */
-
- rowSize= groupsPerLine * groupSize;
- padding= rowSize % psm->unpack_alignment;
- if (padding) {
- rowSize+= psm->unpack_alignment - padding;
- }
-
- imageSize= rowsPerImage * rowSize; /* 3dstuff */
-
- start= (const GLubyte *)userImage + psm->unpack_skip_rows * rowSize +
- psm->unpack_skip_pixels * groupSize +
- /*3dstuff*/
- psm->unpack_skip_images * imageSize;
- elementsPerLine = width * components;
-
- iter2= newImage;
- for (dd= 0; dd < depth; dd++) {
- rowStart= start;
-
- for (hh= 0; hh < height; hh++) {
- iter= rowStart;
-
- for (ww= 0; ww < elementsPerLine; ww++) {
- Type_Widget widget;
- float extractComponents[4];
-
- switch(type) {
- case GL_UNSIGNED_BYTE:
- if (indexFormat) {
- *iter2++ = *iter;
- } else {
- *iter2++ = (*iter) * 257;
- }
- break;
- case GL_BYTE:
- if (indexFormat) {
- *iter2++ = *((const GLbyte *) iter);
- } else {
- /* rough approx */
- *iter2++ = (*((const GLbyte *) iter)) * 516;
- }
- break;
- case GL_UNSIGNED_BYTE_3_3_2:
- extract332(0,iter,extractComponents);
- for (k = 0; k < 3; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- extract233rev(0,iter,extractComponents);
- for (k = 0; k < 3; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- extract565(myswapBytes,iter,extractComponents);
- for (k = 0; k < 3; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- extract565rev(myswapBytes,iter,extractComponents);
- for (k = 0; k < 3; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_UNSIGNED_SHORT_4_4_4_4:
- extract4444(myswapBytes,iter,extractComponents);
- for (k = 0; k < 4; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- extract4444rev(myswapBytes,iter,extractComponents);
- for (k = 0; k < 4; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_UNSIGNED_SHORT_5_5_5_1:
- extract5551(myswapBytes,iter,extractComponents);
- for (k = 0; k < 4; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- extract1555rev(myswapBytes,iter,extractComponents);
- for (k = 0; k < 4; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_UNSIGNED_SHORT:
- case GL_SHORT:
- if (myswapBytes) {
- widget.ub[0] = iter[1];
- widget.ub[1] = iter[0];
- } else {
- widget.ub[0] = iter[0];
- widget.ub[1] = iter[1];
- }
- if (type == GL_SHORT) {
- if (indexFormat) {
- *iter2++ = widget.s[0];
- } else {
- /* rough approx */
- *iter2++ = widget.s[0]*2;
- }
- } else {
- *iter2++ = widget.us[0];
- }
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- extract8888(myswapBytes,iter,extractComponents);
- for (k = 0; k < 4; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- extract8888rev(myswapBytes,iter,extractComponents);
- for (k = 0; k < 4; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_UNSIGNED_INT_10_10_10_2:
- extract1010102(myswapBytes,iter,extractComponents);
- for (k = 0; k < 4; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- extract2101010rev(myswapBytes,iter,extractComponents);
- for (k = 0; k < 4; k++) {
- *iter2++ = (GLushort)(extractComponents[k]*65535);
- }
- break;
- case GL_INT:
- case GL_UNSIGNED_INT:
- case GL_FLOAT:
- if (myswapBytes) {
- widget.ub[0] = iter[3];
- widget.ub[1] = iter[2];
- widget.ub[2] = iter[1];
- widget.ub[3] = iter[0];
- } else {
- widget.ub[0] = iter[0];
- widget.ub[1] = iter[1];
- widget.ub[2] = iter[2];
- widget.ub[3] = iter[3];
- }
- if (type == GL_FLOAT) {
- if (indexFormat) {
- *iter2++ = widget.f;
- } else {
- *iter2++ = 65535 * widget.f;
- }
- } else if (type == GL_UNSIGNED_INT) {
- if (indexFormat) {
- *iter2++ = widget.ui;
- } else {
- *iter2++ = widget.ui >> 16;
- }
- } else {
- if (indexFormat) {
- *iter2++ = widget.i;
- } else {
- *iter2++ = widget.i >> 15;
- }
- }
- break;
- default:
- assert(0);
- }
-
- iter+= elementSize;
- } /* for ww */
- rowStart+= rowSize;
-
- iter= rowStart; /* for assertion purposes */
- } /* for hh */
-
- start+= imageSize;
- } /* for dd */
-
- /* iterators should be one byte past end */
- if (!isTypePackedPixel(type)) {
- assert(iter2 == &newImage[width*height*depth*components]);
- }
- else {
- assert(iter2 == &newImage[width*height*depth*
- elements_per_group(format,0)]);
- }
- assert( iter == &((const GLubyte *)userImage)[rowSize*height*depth +
- psm->unpack_skip_rows * rowSize +
- psm->unpack_skip_pixels * groupSize +
- /*3dstuff*/
- psm->unpack_skip_images * imageSize] );
-} /* fillImage3D () */
-
-static void scaleInternal3D(GLint components,
- GLint widthIn, GLint heightIn, GLint depthIn,
- const GLushort *dataIn,
- GLint widthOut, GLint heightOut, GLint depthOut,
- GLushort *dataOut)
-{
- float x, lowx, highx, convx, halfconvx;
- float y, lowy, highy, convy, halfconvy;
- float z, lowz, highz, convz, halfconvz;
- float xpercent,ypercent,zpercent;
- float percent;
- /* Max components in a format is 4, so... */
- float totals[4];
- float volume;
- int i,j,d,k,zint,yint,xint,xindex,yindex,zindex;
- int temp;
-
- convz = (float) depthIn/depthOut;
- convy = (float) heightIn/heightOut;
- convx = (float) widthIn/widthOut;
- halfconvx = convx/2;
- halfconvy = convy/2;
- halfconvz = convz/2;
- for (d = 0; d < depthOut; d++) {
- z = convz * (d+0.5);
- if (depthIn > depthOut) {
- highz = z + halfconvz;
- lowz = z - halfconvz;
- } else {
- highz = z + 0.5;
- lowz = z - 0.5;
- }
- for (i = 0; i < heightOut; i++) {
- y = convy * (i+0.5);
- if (heightIn > heightOut) {
- highy = y + halfconvy;
- lowy = y - halfconvy;
- } else {
- highy = y + 0.5;
- lowy = y - 0.5;
- }
- for (j = 0; j < widthOut; j++) {
- x = convx * (j+0.5);
- if (widthIn > widthOut) {
- highx = x + halfconvx;
- lowx = x - halfconvx;
- } else {
- highx = x + 0.5;
- lowx = x - 0.5;
- }
-
- /*
- ** Ok, now apply box filter to box that goes from (lowx, lowy,
- ** lowz) to (highx, highy, highz) on input data into this pixel
- ** on output data.
- */
- totals[0] = totals[1] = totals[2] = totals[3] = 0.0;
- volume = 0.0;
-
- z = lowz;
- zint = floor(z);
- while (z < highz) {
- zindex = (zint + depthIn) % depthIn;
- if (highz < zint+1) {
- zpercent = highz - z;
- } else {
- zpercent = zint+1 - z;
- }
-
- y = lowy;
- yint = floor(y);
- while (y < highy) {
- yindex = (yint + heightIn) % heightIn;
- if (highy < yint+1) {
- ypercent = highy - y;
- } else {
- ypercent = yint+1 - y;
- }
-
- x = lowx;
- xint = floor(x);
-
- while (x < highx) {
- xindex = (xint + widthIn) % widthIn;
- if (highx < xint+1) {
- xpercent = highx - x;
- } else {
- xpercent = xint+1 - x;
- }
-
- percent = xpercent * ypercent * zpercent;
- volume += percent;
-
- temp = (xindex + (yindex*widthIn) +
- (zindex*widthIn*heightIn)) * components;
- for (k = 0; k < components; k++) {
- assert(0 <= (temp+k) &&
- (temp+k) <
- (widthIn*heightIn*depthIn*components));
- totals[k] += dataIn[temp + k] * percent;
- }
-
- xint++;
- x = xint;
- } /* while x */
-
- yint++;
- y = yint;
- } /* while y */
-
- zint++;
- z = zint;
- } /* while z */
-
- temp = (j + (i * widthOut) +
- (d*widthOut*heightOut)) * components;
- for (k = 0; k < components; k++) {
- /* totals[] should be rounded in the case of enlarging an
- * RGB ramp when the type is 332 or 4444
- */
- assert(0 <= (temp+k) &&
- (temp+k) < (widthOut*heightOut*depthOut*components));
- dataOut[temp + k] = (totals[k]+0.5)/volume;
- }
- } /* for j */
- } /* for i */
- } /* for d */
-} /* scaleInternal3D() */
-
-static void emptyImage3D(const PixelStorageModes *psm,
- GLint width, GLint height, GLint depth,
- GLenum format, GLenum type, GLboolean indexFormat,
- const GLushort *oldImage, void *userImage)
-{
- int myswapBytes;
- int components;
- int groupsPerLine;
- int elementSize;
- int groupSize;
- int rowSize;
- int padding;
- GLubyte *start, *rowStart, *iter;
- int elementsPerLine;
- const GLushort *iter2;
- int ii, jj, dd, k;
- int rowsPerImage;
- int imageSize;
-
- myswapBytes= psm->pack_swap_bytes;
- components = elements_per_group(format,type);
- if (psm->pack_row_length > 0) {
- groupsPerLine = psm->pack_row_length;
- }
- else {
- groupsPerLine = width;
- }
-
- elementSize= bytes_per_element(type);
- groupSize= elementSize * components;
- if (elementSize == 1) myswapBytes= 0;
-
- /* 3dstuff begin */
- if (psm->pack_image_height > 0) {
- rowsPerImage= psm->pack_image_height;
- }
- else {
- rowsPerImage= height;
- }
-
- /* 3dstuff end */
-
- rowSize = groupsPerLine * groupSize;
- padding = rowSize % psm->pack_alignment;
- if (padding) {
- rowSize+= psm->pack_alignment - padding;
- }
-
- imageSize= rowsPerImage * rowSize; /* 3dstuff */
-
- start = (GLubyte *)userImage + psm->pack_skip_rows * rowSize +
- psm->pack_skip_pixels * groupSize +
- /*3dstuff*/
- psm->pack_skip_images * imageSize;
- elementsPerLine= width * components;
-
- iter2 = oldImage;
- for (dd= 0; dd < depth; dd++) {
- rowStart= start;
-
- for (ii= 0; ii< height; ii++) {
- iter = rowStart;
-
- for (jj = 0; jj < elementsPerLine; jj++) {
- Type_Widget widget;
- float shoveComponents[4];
-
- switch(type){
- case GL_UNSIGNED_BYTE:
- if (indexFormat) {
- *iter = *iter2++;
- } else {
- *iter = *iter2++ >> 8;
- }
- break;
- case GL_BYTE:
- if (indexFormat) {
- *((GLbyte *) iter) = *iter2++;
- } else {
- *((GLbyte *) iter) = *iter2++ >> 9;
- }
- break;
- case GL_UNSIGNED_BYTE_3_3_2:
- for (k = 0; k < 3; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove332(shoveComponents,0,(void *)iter);
- break;
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- for (k = 0; k < 3; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove233rev(shoveComponents,0,(void *)iter);
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- for (k = 0; k < 3; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove565(shoveComponents,0,(void *)&widget.us[0]);
- if (myswapBytes) {
- iter[0] = widget.ub[1];
- iter[1] = widget.ub[0];
- }
- else {
- *(GLushort *)iter = widget.us[0];
- }
- break;
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- for (k = 0; k < 3; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove565rev(shoveComponents,0,(void *)&widget.us[0]);
- if (myswapBytes) {
- iter[0] = widget.ub[1];
- iter[1] = widget.ub[0];
- }
- else {
- *(GLushort *)iter = widget.us[0];
- }
- break;
- case GL_UNSIGNED_SHORT_4_4_4_4:
- for (k = 0; k < 4; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove4444(shoveComponents,0,(void *)&widget.us[0]);
- if (myswapBytes) {
- iter[0] = widget.ub[1];
- iter[1] = widget.ub[0];
- } else {
- *(GLushort *)iter = widget.us[0];
- }
- break;
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- for (k = 0; k < 4; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove4444rev(shoveComponents,0,(void *)&widget.us[0]);
- if (myswapBytes) {
- iter[0] = widget.ub[1];
- iter[1] = widget.ub[0];
- } else {
- *(GLushort *)iter = widget.us[0];
- }
- break;
- case GL_UNSIGNED_SHORT_5_5_5_1:
- for (k = 0; k < 4; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove5551(shoveComponents,0,(void *)&widget.us[0]);
- if (myswapBytes) {
- iter[0] = widget.ub[1];
- iter[1] = widget.ub[0];
- } else {
- *(GLushort *)iter = widget.us[0];
- }
- break;
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- for (k = 0; k < 4; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove1555rev(shoveComponents,0,(void *)&widget.us[0]);
- if (myswapBytes) {
- iter[0] = widget.ub[1];
- iter[1] = widget.ub[0];
- } else {
- *(GLushort *)iter = widget.us[0];
- }
- break;
- case GL_UNSIGNED_SHORT:
- case GL_SHORT:
- if (type == GL_SHORT) {
- if (indexFormat) {
- widget.s[0] = *iter2++;
- } else {
- widget.s[0] = *iter2++ >> 1;
- }
- } else {
- widget.us[0] = *iter2++;
- }
- if (myswapBytes) {
- iter[0] = widget.ub[1];
- iter[1] = widget.ub[0];
- } else {
- iter[0] = widget.ub[0];
- iter[1] = widget.ub[1];
- }
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- for (k = 0; k < 4; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove8888(shoveComponents,0,(void *)&widget.ui);
- if (myswapBytes) {
- iter[3] = widget.ub[0];
- iter[2] = widget.ub[1];
- iter[1] = widget.ub[2];
- iter[0] = widget.ub[3];
- } else {
- *(GLuint *)iter= widget.ui;
- }
- break;
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- for (k = 0; k < 4; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove8888rev(shoveComponents,0,(void *)&widget.ui);
- if (myswapBytes) {
- iter[3] = widget.ub[0];
- iter[2] = widget.ub[1];
- iter[1] = widget.ub[2];
- iter[0] = widget.ub[3];
- } else {
- *(GLuint *)iter= widget.ui;
- }
- break;
- case GL_UNSIGNED_INT_10_10_10_2:
- for (k = 0; k < 4; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove1010102(shoveComponents,0,(void *)&widget.ui);
- if (myswapBytes) {
- iter[3] = widget.ub[0];
- iter[2] = widget.ub[1];
- iter[1] = widget.ub[2];
- iter[0] = widget.ub[3];
- } else {
- *(GLuint *)iter= widget.ui;
- }
- break;
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- for (k = 0; k < 4; k++) {
- shoveComponents[k]= *iter2++ / 65535.0;
- }
- shove2101010rev(shoveComponents,0,(void *)&widget.ui);
- if (myswapBytes) {
- iter[3] = widget.ub[0];
- iter[2] = widget.ub[1];
- iter[1] = widget.ub[2];
- iter[0] = widget.ub[3];
- } else {
- *(GLuint *)iter= widget.ui;
- }
- break;
- case GL_INT:
- case GL_UNSIGNED_INT:
- case GL_FLOAT:
- if (type == GL_FLOAT) {
- if (indexFormat) {
- widget.f = *iter2++;
- } else {
- widget.f = *iter2++ / (float) 65535.0;
- }
- } else if (type == GL_UNSIGNED_INT) {
- if (indexFormat) {
- widget.ui = *iter2++;
- } else {
- widget.ui = (unsigned int) *iter2++ * 65537;
- }
- } else {
- if (indexFormat) {
- widget.i = *iter2++;
- } else {
- widget.i = ((unsigned int) *iter2++ * 65537)/2;
- }
- }
- if (myswapBytes) {
- iter[3] = widget.ub[0];
- iter[2] = widget.ub[1];
- iter[1] = widget.ub[2];
- iter[0] = widget.ub[3];
- } else {
- iter[0] = widget.ub[0];
- iter[1] = widget.ub[1];
- iter[2] = widget.ub[2];
- iter[3] = widget.ub[3];
- }
- break;
- default:
- assert(0);
- }
-
- iter+= elementSize;
- } /* for jj */
-
- rowStart+= rowSize;
- } /* for ii */
-
- start+= imageSize;
- } /* for dd */
-
- /* iterators should be one byte past end */
- if (!isTypePackedPixel(type)) {
- assert(iter2 == &oldImage[width*height*depth*components]);
- }
- else {
- assert(iter2 == &oldImage[width*height*depth*
- elements_per_group(format,0)]);
- }
- assert( iter == &((GLubyte *)userImage)[rowSize*height*depth +
- psm->unpack_skip_rows * rowSize +
- psm->unpack_skip_pixels * groupSize +
- /*3dstuff*/
- psm->unpack_skip_images * imageSize] );
-} /* emptyImage3D() */
-
-static
-int gluScaleImage3D(GLenum format,
- GLint widthIn, GLint heightIn, GLint depthIn,
- GLenum typeIn, const void *dataIn,
- GLint widthOut, GLint heightOut, GLint depthOut,
- GLenum typeOut, void *dataOut)
-{
- int components;
- GLushort *beforeImage, *afterImage;
- PixelStorageModes psm;
-
- if (widthIn == 0 || heightIn == 0 || depthIn == 0 ||
- widthOut == 0 || heightOut == 0 || depthOut == 0) {
- return 0;
- }
-
- if (widthIn < 0 || heightIn < 0 || depthIn < 0 ||
- widthOut < 0 || heightOut < 0 || depthOut < 0) {
- return GLU_INVALID_VALUE;
- }
-
- if (!legalFormat(format) || !legalType(typeIn) || !legalType(typeOut) ||
- typeIn == GL_BITMAP || typeOut == GL_BITMAP) {
- return GLU_INVALID_ENUM;
- }
- if (!isLegalFormatForPackedPixelType(format, typeIn)) {
- return GLU_INVALID_OPERATION;
- }
- if (!isLegalFormatForPackedPixelType(format, typeOut)) {
- return GLU_INVALID_OPERATION;
- }
-
- beforeImage = malloc(imageSize3D(widthIn, heightIn, depthIn, format,
- GL_UNSIGNED_SHORT));
- afterImage = malloc(imageSize3D(widthOut, heightOut, depthOut, format,
- GL_UNSIGNED_SHORT));
- if (beforeImage == NULL || afterImage == NULL) {
- free(beforeImage);
- free(afterImage);
- return GLU_OUT_OF_MEMORY;
- }
- retrieveStoreModes3D(&psm);
-
- fillImage3D(&psm,widthIn,heightIn,depthIn,format,typeIn, is_index(format),
- dataIn, beforeImage);
- components = elements_per_group(format,0);
- scaleInternal3D(components,widthIn,heightIn,depthIn,beforeImage,
- widthOut,heightOut,depthOut,afterImage);
- emptyImage3D(&psm,widthOut,heightOut,depthOut,format,typeOut,
- is_index(format),afterImage, dataOut);
- free((void *) beforeImage);
- free((void *) afterImage);
-
- return 0;
-} /* gluScaleImage3D() */
-
-
-static void closestFit3D(GLenum target, GLint width, GLint height, GLint depth,
- GLint internalFormat, GLenum format, GLenum type,
- GLint *newWidth, GLint *newHeight, GLint *newDepth)
-{
- GLint widthPowerOf2= nearestPower(width);
- GLint heightPowerOf2= nearestPower(height);
- GLint depthPowerOf2= nearestPower(depth);
- GLint proxyWidth;
-
- do {
- /* compute level 1 width & height & depth, clamping each at 1 */
- GLint widthAtLevelOne= (widthPowerOf2 > 1) ?
- widthPowerOf2 >> 1 :
- widthPowerOf2;
- GLint heightAtLevelOne= (heightPowerOf2 > 1) ?
- heightPowerOf2 >> 1 :
- heightPowerOf2;
- GLint depthAtLevelOne= (depthPowerOf2 > 1) ?
- depthPowerOf2 >> 1 :
- depthPowerOf2;
- GLenum proxyTarget = GL_PROXY_TEXTURE_3D;
- assert(widthAtLevelOne > 0);
- assert(heightAtLevelOne > 0);
- assert(depthAtLevelOne > 0);
-
- /* does width x height x depth at level 1 & all their mipmaps fit? */
- assert(target == GL_TEXTURE_3D || target == GL_PROXY_TEXTURE_3D);
- gluTexImage3D(proxyTarget, 1, /* must be non-zero */
- internalFormat,
- widthAtLevelOne,heightAtLevelOne,depthAtLevelOne,
- 0,format,type,NULL);
- glGetTexLevelParameteriv(proxyTarget, 1,GL_TEXTURE_WIDTH,&proxyWidth);
- /* does it fit??? */
- if (proxyWidth == 0) { /* nope, so try again with these sizes */
- if (widthPowerOf2 == 1 && heightPowerOf2 == 1 &&
- depthPowerOf2 == 1) {
- *newWidth= *newHeight= *newDepth= 1; /* must fit 1x1x1 texture */
- return;
- }
- widthPowerOf2= widthAtLevelOne;
- heightPowerOf2= heightAtLevelOne;
- depthPowerOf2= depthAtLevelOne;
- }
- /* else it does fit */
- } while (proxyWidth == 0);
- /* loop must terminate! */
-
- /* return the width & height at level 0 that fits */
- *newWidth= widthPowerOf2;
- *newHeight= heightPowerOf2;
- *newDepth= depthPowerOf2;
-/*printf("Proxy Textures\n");*/
-} /* closestFit3D() */
-
-static void halveImagePackedPixelSlice(int components,
- void (*extractPackedPixel)
- (int, const void *,GLfloat []),
- void (*shovePackedPixel)
- (const GLfloat [],int, void *),
- GLint width, GLint height, GLint depth,
- const void *dataIn, void *dataOut,
- GLint pixelSizeInBytes,
- GLint rowSizeInBytes,
- GLint imageSizeInBytes,
- GLint isSwap)
-{
- int ii, jj;
- int halfWidth= width / 2;
- int halfHeight= height / 2;
- int halfDepth= depth / 2;
- const char *src= (const char *)dataIn;
- int outIndex= 0;
-
- assert((width == 1 || height == 1) && depth >= 2);
-
- if (width == height) { /* a 1-pixel column viewed from top */
- assert(width == 1 && height == 1);
- assert(depth >= 2);
-
- for (ii= 0; ii< halfDepth; ii++) {
- float totals[4];
- float extractTotals[BOX2][4];
- int cc;
-
- (*extractPackedPixel)(isSwap,src,&extractTotals[0][0]);
- (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
- &extractTotals[1][0]);
- for (cc = 0; cc < components; cc++) {
- int kk;
-
- /* average 2 pixels since only a column */
- totals[cc]= 0.0;
- /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
- * totals[RED]/= 2.0;
- */
- for (kk = 0; kk < BOX2; kk++) {
- totals[cc]+= extractTotals[kk][cc];
- }
- totals[cc]/= (float)BOX2;
- } /* for cc */
-
- (*shovePackedPixel)(totals,outIndex,dataOut);
- outIndex++;
- /* skip over to next group of 2 */
- src+= imageSizeInBytes + imageSizeInBytes;
- } /* for ii */
- }
- else if (height == 1) { /* horizontal slice viewed from top */
- assert(width != 1);
-
- for (ii= 0; ii< halfDepth; ii++) {
- for (jj= 0; jj< halfWidth; jj++) {
- float totals[4];
- float extractTotals[BOX4][4];
- int cc;
-
- (*extractPackedPixel)(isSwap,src,
- &extractTotals[0][0]);
- (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
- &extractTotals[1][0]);
- (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
- &extractTotals[2][0]);
- (*extractPackedPixel)(isSwap,
- (src+imageSizeInBytes+pixelSizeInBytes),
- &extractTotals[3][0]);
- for (cc = 0; cc < components; cc++) {
- int kk;
-
- /* grab 4 pixels to average */
- totals[cc]= 0.0;
- /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
- * extractTotals[2][RED]+extractTotals[3][RED];
- * totals[RED]/= 4.0;
- */
- for (kk = 0; kk < BOX4; kk++) {
- totals[cc]+= extractTotals[kk][cc];
- }
- totals[cc]/= (float)BOX4;
- }
- (*shovePackedPixel)(totals,outIndex,dataOut);
-
- outIndex++;
- /* skip over to next horizontal square of 4 */
- src+= imageSizeInBytes + imageSizeInBytes;
- }
- }
-
- /* assert() */
- }
- else if (width == 1) { /* vertical slice viewed from top */
- assert(height != 1);
-
- for (ii= 0; ii< halfDepth; ii++) {
- for (jj= 0; jj< halfHeight; jj++) {
- float totals[4];
- float extractTotals[BOX4][4];
- int cc;
-
- (*extractPackedPixel)(isSwap,src,
- &extractTotals[0][0]);
- (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
- &extractTotals[1][0]);
- (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
- &extractTotals[2][0]);
- (*extractPackedPixel)(isSwap,
- (src+imageSizeInBytes+rowSizeInBytes),
- &extractTotals[3][0]);
- for (cc = 0; cc < components; cc++) {
- int kk;
-
- /* grab 4 pixels to average */
- totals[cc]= 0.0;
- /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
- * extractTotals[2][RED]+extractTotals[3][RED];
- * totals[RED]/= 4.0;
- */
- for (kk = 0; kk < BOX4; kk++) {
- totals[cc]+= extractTotals[kk][cc];
- }
- totals[cc]/= (float)BOX4;
- }
- (*shovePackedPixel)(totals,outIndex,dataOut);
-
- outIndex++;
-
- /* skip over to next vertical square of 4 */
- src+= imageSizeInBytes + imageSizeInBytes;
- }
- }
- /* assert() */
- }
-
-} /* halveImagePackedPixelSlice() */
-
-static void halveImagePackedPixel3D(int components,
- void (*extractPackedPixel)
- (int, const void *,GLfloat []),
- void (*shovePackedPixel)
- (const GLfloat [],int, void *),
- GLint width, GLint height, GLint depth,
- const void *dataIn, void *dataOut,
- GLint pixelSizeInBytes,
- GLint rowSizeInBytes,
- GLint imageSizeInBytes,
- GLint isSwap)
-{
- if (depth == 1) {
- assert(1 <= width && 1 <= height);
-
- halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel,
- width,height,dataIn,dataOut,pixelSizeInBytes,
- rowSizeInBytes,isSwap);
- return;
- }
- /* a horizontal or vertical slice viewed from top */
- else if (width == 1 || height == 1) {
- assert(1 <= depth);
-
- halveImagePackedPixelSlice(components,
- extractPackedPixel,shovePackedPixel,
- width, height, depth, dataIn, dataOut,
- pixelSizeInBytes, rowSizeInBytes,
- imageSizeInBytes, isSwap);
- return;
- }
- {
- int ii, jj, dd;
-
- int halfWidth= width / 2;
- int halfHeight= height / 2;
- int halfDepth= depth / 2;
- const char *src= (const char *) dataIn;
- int padBytes= rowSizeInBytes - (width*pixelSizeInBytes);
- int outIndex= 0;
-
- for (dd= 0; dd < halfDepth; dd++) {
- for (ii= 0; ii< halfHeight; ii++) {
- for (jj= 0; jj< halfWidth; jj++) {
-#define BOX8 8
- float totals[4]; /* 4 is maximum components */
- float extractTotals[BOX8][4]; /* 4 is maximum components */
- int cc;
-
- (*extractPackedPixel)(isSwap,src,
- &extractTotals[0][0]);
- (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes),
- &extractTotals[1][0]);
- (*extractPackedPixel)(isSwap,(src+rowSizeInBytes),
- &extractTotals[2][0]);
- (*extractPackedPixel)(isSwap,
- (src+rowSizeInBytes+pixelSizeInBytes),
- &extractTotals[3][0]);
-
- (*extractPackedPixel)(isSwap,(src+imageSizeInBytes),
- &extractTotals[4][0]);
- (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes+imageSizeInBytes),
- &extractTotals[5][0]);
- (*extractPackedPixel)(isSwap,(src+rowSizeInBytes+imageSizeInBytes),
- &extractTotals[6][0]);
- (*extractPackedPixel)(isSwap,
- (src+rowSizeInBytes+pixelSizeInBytes+imageSizeInBytes),
- &extractTotals[7][0]);
- for (cc = 0; cc < components; cc++) {
- int kk;
-
- /* grab 8 pixels to average */
- totals[cc]= 0.0;
- /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
- * extractTotals[2][RED]+extractTotals[3][RED]+
- * extractTotals[4][RED]+extractTotals[5][RED]+
- * extractTotals[6][RED]+extractTotals[7][RED];
- * totals[RED]/= 8.0;
- */
- for (kk = 0; kk < BOX8; kk++) {
- totals[cc]+= extractTotals[kk][cc];
- }
- totals[cc]/= (float)BOX8;
- }
- (*shovePackedPixel)(totals,outIndex,dataOut);
-
- outIndex++;
- /* skip over to next square of 4 */
- src+= pixelSizeInBytes + pixelSizeInBytes;
- }
- /* skip past pad bytes, if any, to get to next row */
- src+= padBytes;
-
- /* src is at beginning of a row here, but it's the second row of
- * the square block of 4 pixels that we just worked on so we
- * need to go one more row.
- * i.e.,
- * OO...
- * here -->OO...
- * but want -->OO...
- * OO...
- * ...
- */
- src+= rowSizeInBytes;
- }
-
- src+= imageSizeInBytes;
- } /* for dd */
-
- /* both pointers must reach one byte after the end */
- assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
- assert(outIndex == halfWidth * halfHeight * halfDepth);
- } /* for dd */
-
-} /* halveImagePackedPixel3D() */
-
-static int gluBuild3DMipmapLevelsCore(GLenum target, GLint internalFormat,
- GLsizei width,
- GLsizei height,
- GLsizei depth,
- GLsizei widthPowerOf2,
- GLsizei heightPowerOf2,
- GLsizei depthPowerOf2,
- GLenum format, GLenum type,
- GLint userLevel,
- GLint baseLevel,GLint maxLevel,
- const void *data)
-{
- GLint newWidth, newHeight, newDepth;
- GLint level, levels;
- const void *usersImage;
- void *srcImage, *dstImage;
- __GLU_INIT_SWAP_IMAGE;
- GLint memReq;
- GLint cmpts;
-
- GLint myswapBytes, groupsPerLine, elementSize, groupSize;
- GLint rowsPerImage, imageSize;
- GLint rowSize, padding;
- PixelStorageModes psm;
-
- assert(checkMipmapArgs(internalFormat,format,type) == 0);
- assert(width >= 1 && height >= 1 && depth >= 1);
- assert(type != GL_BITMAP);
-
- srcImage = dstImage = NULL;
-
- newWidth= widthPowerOf2;
- newHeight= heightPowerOf2;
- newDepth= depthPowerOf2;
- levels = computeLog(newWidth);
- level = computeLog(newHeight);
- if (level > levels) levels=level;
- level = computeLog(newDepth);
- if (level > levels) levels=level;
-
- levels+= userLevel;
-
- retrieveStoreModes3D(&psm);
- myswapBytes = psm.unpack_swap_bytes;
- cmpts = elements_per_group(format,type);
- if (psm.unpack_row_length > 0) {
- groupsPerLine = psm.unpack_row_length;
- } else {
- groupsPerLine = width;
- }
-
- elementSize = bytes_per_element(type);
- groupSize = elementSize * cmpts;
- if (elementSize == 1) myswapBytes = 0;
-
- /* 3dstuff begin */
- if (psm.unpack_image_height > 0) {
- rowsPerImage= psm.unpack_image_height;
- }
- else {
- rowsPerImage= height;
- }
-
- /* 3dstuff end */
- rowSize = groupsPerLine * groupSize;
- padding = (rowSize % psm.unpack_alignment);
- if (padding) {
- rowSize += psm.unpack_alignment - padding;
- }
-
- imageSize= rowsPerImage * rowSize; /* 3dstuff */
-
- usersImage = (const GLubyte *)data + psm.unpack_skip_rows * rowSize +
- psm.unpack_skip_pixels * groupSize +
- /* 3dstuff */
- psm.unpack_skip_images * imageSize;
-
- glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0);
- glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
-
- level = userLevel;
-
- if (width == newWidth && height == newHeight && depth == newDepth) {
- /* Use usersImage for level userLevel */
- if (baseLevel <= level && level <= maxLevel) {
- gluTexImage3D(target, level, internalFormat, width,
- height, depth, 0, format, type,
- usersImage);
- }
- if(levels == 0) { /* we're done. clean up and return */
- glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
- glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
- glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
- return 0;
- }
- {
- int nextWidth= newWidth/2;
- int nextHeight= newHeight/2;
- int nextDepth= newDepth/2;
-
- /* clamp to 1 */
- if (nextWidth < 1) nextWidth= 1;
- if (nextHeight < 1) nextHeight= 1;
- if (nextDepth < 1) nextDepth= 1;
- memReq = imageSize3D(nextWidth, nextHeight, nextDepth, format, type);
- }
- switch(type) {
- case GL_UNSIGNED_BYTE:
- dstImage = (GLubyte *)malloc(memReq);
- break;
- case GL_BYTE:
- dstImage = (GLbyte *)malloc(memReq);
- break;
- case GL_UNSIGNED_SHORT:
- dstImage = (GLushort *)malloc(memReq);
- break;
- case GL_SHORT:
- dstImage = (GLshort *)malloc(memReq);
- break;
- case GL_UNSIGNED_INT:
- dstImage = (GLuint *)malloc(memReq);
- break;
- case GL_INT:
- dstImage = (GLint *)malloc(memReq);
- break;
- case GL_FLOAT:
- dstImage = (GLfloat *)malloc(memReq);
- break;
- case GL_UNSIGNED_BYTE_3_3_2:
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- dstImage = (GLubyte *)malloc(memReq);
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- dstImage = (GLushort *)malloc(memReq);
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- case GL_UNSIGNED_INT_10_10_10_2:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- dstImage = (GLuint *)malloc(memReq);
- break;
- default:
- return GLU_INVALID_ENUM; /* assertion */
- }
- if (dstImage == NULL) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
- glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
- glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
- return GLU_OUT_OF_MEMORY;
- }
- else
- switch(type) {
- case GL_UNSIGNED_BYTE:
- if (depth > 1) {
- halveImage3D(cmpts,extractUbyte,shoveUbyte,
- width,height,depth,
- usersImage,dstImage,elementSize,groupSize,rowSize,
- imageSize,myswapBytes);
- }
- else {
- halveImage_ubyte(cmpts,width,height,usersImage,dstImage,
- elementSize,rowSize,groupSize);
- }
- break;
- case GL_BYTE:
- if (depth > 1) {
- halveImage3D(cmpts,extractSbyte,shoveSbyte,
- width,height,depth,
- usersImage,dstImage,elementSize,groupSize,rowSize,
- imageSize,myswapBytes);
- }
- else {
- halveImage_byte(cmpts,width,height,usersImage,dstImage,
- elementSize,rowSize,groupSize);
- }
- break;
- case GL_UNSIGNED_SHORT:
- if (depth > 1) {
- halveImage3D(cmpts,extractUshort,shoveUshort,
- width,height,depth,
- usersImage,dstImage,elementSize,groupSize,rowSize,
- imageSize,myswapBytes);
- }
- else {
- halveImage_ushort(cmpts,width,height,usersImage,dstImage,
- elementSize,rowSize,groupSize,myswapBytes);
- }
- break;
- case GL_SHORT:
- if (depth > 1) {
- halveImage3D(cmpts,extractSshort,shoveSshort,
- width,height,depth,
- usersImage,dstImage,elementSize,groupSize,rowSize,
- imageSize,myswapBytes);
- }
- else {
- halveImage_short(cmpts,width,height,usersImage,dstImage,
- elementSize,rowSize,groupSize,myswapBytes);
- }
- break;
- case GL_UNSIGNED_INT:
- if (depth > 1) {
- halveImage3D(cmpts,extractUint,shoveUint,
- width,height,depth,
- usersImage,dstImage,elementSize,groupSize,rowSize,
- imageSize,myswapBytes);
- }
- else {
- halveImage_uint(cmpts,width,height,usersImage,dstImage,
- elementSize,rowSize,groupSize,myswapBytes);
- }
- break;
- case GL_INT:
- if (depth > 1) {
- halveImage3D(cmpts,extractSint,shoveSint,
- width,height,depth,
- usersImage,dstImage,elementSize,groupSize,rowSize,
- imageSize,myswapBytes);
- }
- else {
- halveImage_int(cmpts,width,height,usersImage,dstImage,
- elementSize,rowSize,groupSize,myswapBytes);
- }
- break;
- case GL_FLOAT:
- if (depth > 1 ) {
- halveImage3D(cmpts,extractFloat,shoveFloat,
- width,height,depth,
- usersImage,dstImage,elementSize,groupSize,rowSize,
- imageSize,myswapBytes);
- }
- else {
- halveImage_float(cmpts,width,height,usersImage,dstImage,
- elementSize,rowSize,groupSize,myswapBytes);
- }
- break;
- case GL_UNSIGNED_BYTE_3_3_2:
- assert(format == GL_RGB);
- halveImagePackedPixel3D(3,extract332,shove332,
- width,height,depth,usersImage,dstImage,
- elementSize,rowSize,imageSize,myswapBytes);
- break;
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- assert(format == GL_RGB);
- halveImagePackedPixel3D(3,extract233rev,shove233rev,
- width,height,depth,usersImage,dstImage,
- elementSize,rowSize,imageSize,myswapBytes);
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- halveImagePackedPixel3D(3,extract565,shove565,
- width,height,depth,usersImage,dstImage,
- elementSize,rowSize,imageSize,myswapBytes);
- break;
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- halveImagePackedPixel3D(3,extract565rev,shove565rev,
- width,height,depth,usersImage,dstImage,
- elementSize,rowSize,imageSize,myswapBytes);
- break;
- case GL_UNSIGNED_SHORT_4_4_4_4:
- halveImagePackedPixel3D(4,extract4444,shove4444,
- width,height,depth,usersImage,dstImage,
- elementSize,rowSize,imageSize,myswapBytes);
- break;
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- halveImagePackedPixel3D(4,extract4444rev,shove4444rev,
- width,height,depth,usersImage,dstImage,
- elementSize,rowSize,imageSize,myswapBytes);
- break;
- case GL_UNSIGNED_SHORT_5_5_5_1:
- halveImagePackedPixel3D(4,extract5551,shove5551,
- width,height,depth,usersImage,dstImage,
- elementSize,rowSize,imageSize,myswapBytes);
- break;
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- halveImagePackedPixel3D(4,extract1555rev,shove1555rev,
- width,height,depth,usersImage,dstImage,
- elementSize,rowSize,imageSize,myswapBytes);
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- halveImagePackedPixel3D(4,extract8888,shove8888,
- width,height,depth,usersImage,dstImage,
- elementSize,rowSize,imageSize,myswapBytes);
- break;
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- halveImagePackedPixel3D(4,extract8888rev,shove8888rev,
- width,height,depth,usersImage,dstImage,
- elementSize,rowSize,imageSize,myswapBytes);
- break;
- case GL_UNSIGNED_INT_10_10_10_2:
- halveImagePackedPixel3D(4,extract1010102,shove1010102,
- width,height,depth,usersImage,dstImage,
- elementSize,rowSize,imageSize,myswapBytes);
- break;
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- halveImagePackedPixel3D(4,extract2101010rev,shove2101010rev,
- width,height,depth,usersImage,dstImage,
- elementSize,rowSize,imageSize,myswapBytes);
- break;
- default:
- assert(0);
- break;
- }
- newWidth = width/2;
- newHeight = height/2;
- newDepth = depth/2;
- /* clamp to 1 */
- if (newWidth < 1) newWidth= 1;
- if (newHeight < 1) newHeight= 1;
- if (newDepth < 1) newDepth= 1;
-
- myswapBytes = 0;
- rowSize = newWidth * groupSize;
- imageSize= rowSize * newHeight; /* 3dstuff */
- memReq = imageSize3D(newWidth, newHeight, newDepth, format, type);
- /* Swap srcImage and dstImage */
- __GLU_SWAP_IMAGE(srcImage,dstImage);
- switch(type) {
- case GL_UNSIGNED_BYTE:
- dstImage = (GLubyte *)malloc(memReq);
- break;
- case GL_BYTE:
- dstImage = (GLbyte *)malloc(memReq);
- break;
- case GL_UNSIGNED_SHORT:
- dstImage = (GLushort *)malloc(memReq);
- break;
- case GL_SHORT:
- dstImage = (GLshort *)malloc(memReq);
- break;
- case GL_UNSIGNED_INT:
- dstImage = (GLuint *)malloc(memReq);
- break;
- case GL_INT:
- dstImage = (GLint *)malloc(memReq);
- break;
- case GL_FLOAT:
- dstImage = (GLfloat *)malloc(memReq);
- break;
- case GL_UNSIGNED_BYTE_3_3_2:
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- dstImage = (GLubyte *)malloc(memReq);
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- dstImage = (GLushort *)malloc(memReq);
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- case GL_UNSIGNED_INT_10_10_10_2:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- dstImage = (GLuint *)malloc(memReq);
- break;
- default:
- return GLU_INVALID_ENUM; /* assertion */
- }
- if (dstImage == NULL) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
- glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
- glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
- free(srcImage);
- return GLU_OUT_OF_MEMORY;
- }
- /* level userLevel+1 is in srcImage; level userLevel already saved */
- level = userLevel+1;
- } else {/* user's image is *not* nice power-of-2 sized square */
- memReq = imageSize3D(newWidth, newHeight, newDepth, format, type);
- switch(type) {
- case GL_UNSIGNED_BYTE:
- dstImage = (GLubyte *)malloc(memReq);
- break;
- case GL_BYTE:
- dstImage = (GLbyte *)malloc(memReq);
- break;
- case GL_UNSIGNED_SHORT:
- dstImage = (GLushort *)malloc(memReq);
- break;
- case GL_SHORT:
- dstImage = (GLshort *)malloc(memReq);
- break;
- case GL_UNSIGNED_INT:
- dstImage = (GLuint *)malloc(memReq);
- break;
- case GL_INT:
- dstImage = (GLint *)malloc(memReq);
- break;
- case GL_FLOAT:
- dstImage = (GLfloat *)malloc(memReq);
- break;
- case GL_UNSIGNED_BYTE_3_3_2:
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- dstImage = (GLubyte *)malloc(memReq);
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- dstImage = (GLushort *)malloc(memReq);
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- case GL_UNSIGNED_INT_10_10_10_2:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- dstImage = (GLuint *)malloc(memReq);
- break;
- default:
- return GLU_INVALID_ENUM; /* assertion */
- }
-
- if (dstImage == NULL) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
- glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
- glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
- return GLU_OUT_OF_MEMORY;
- }
- /*printf("Build3DMipmaps(): ScaleImage3D %d %d %d->%d %d %d\n",
- width,height,depth,newWidth,newHeight,newDepth);*/
-
- gluScaleImage3D(format, width, height, depth, type, usersImage,
- newWidth, newHeight, newDepth, type, dstImage);
-
- myswapBytes = 0;
- rowSize = newWidth * groupSize;
- imageSize = rowSize * newHeight; /* 3dstuff */
- /* Swap dstImage and srcImage */
- __GLU_SWAP_IMAGE(srcImage,dstImage);
-
- if(levels != 0) { /* use as little memory as possible */
- {
- int nextWidth= newWidth/2;
- int nextHeight= newHeight/2;
- int nextDepth= newDepth/2;
- if (nextWidth < 1) nextWidth= 1;
- if (nextHeight < 1) nextHeight= 1;
- if (nextDepth < 1) nextDepth= 1;
-
- memReq = imageSize3D(nextWidth, nextHeight, nextDepth, format, type);
- }
- switch(type) {
- case GL_UNSIGNED_BYTE:
- dstImage = (GLubyte *)malloc(memReq);
- break;
- case GL_BYTE:
- dstImage = (GLbyte *)malloc(memReq);
- break;
- case GL_UNSIGNED_SHORT:
- dstImage = (GLushort *)malloc(memReq);
- break;
- case GL_SHORT:
- dstImage = (GLshort *)malloc(memReq);
- break;
- case GL_UNSIGNED_INT:
- dstImage = (GLuint *)malloc(memReq);
- break;
- case GL_INT:
- dstImage = (GLint *)malloc(memReq);
- break;
- case GL_FLOAT:
- dstImage = (GLfloat *)malloc(memReq);
- break;
- case GL_UNSIGNED_BYTE_3_3_2:
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- dstImage = (GLubyte *)malloc(memReq);
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- dstImage = (GLushort *)malloc(memReq);
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- case GL_UNSIGNED_INT_10_10_10_2:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- dstImage = (GLuint *)malloc(memReq);
- break;
- default:
- return GLU_INVALID_ENUM; /* assertion */
- }
- if (dstImage == NULL) {
- glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
- glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
- glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
- free(srcImage);
- return GLU_OUT_OF_MEMORY;
- }
- }
- /* level userLevel is in srcImage; nothing saved yet */
- level = userLevel;
- }
-
- glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
- if (baseLevel <= level && level <= maxLevel) {
- gluTexImage3D(target, level, internalFormat, newWidth, newHeight, newDepth,
- 0,format, type, (void *)srcImage);
- }
- level++; /* update current level for the loop */
- for (; level <= levels; level++) {
- switch(type) {
- case GL_UNSIGNED_BYTE:
- if (newDepth > 1) {
- halveImage3D(cmpts,extractUbyte,shoveUbyte,
- newWidth,newHeight,newDepth,
- srcImage,dstImage,elementSize,groupSize,rowSize,
- imageSize,myswapBytes);
- }
- else {
- halveImage_ubyte(cmpts,newWidth,newHeight,srcImage,dstImage,
- elementSize,rowSize,groupSize);
- }
- break;
- case GL_BYTE:
- if (newDepth > 1) {
- halveImage3D(cmpts,extractSbyte,shoveSbyte,
- newWidth,newHeight,newDepth,
- srcImage,dstImage,elementSize,groupSize,rowSize,
- imageSize,myswapBytes);
- }
- else {
- halveImage_byte(cmpts,newWidth,newHeight,srcImage,dstImage,
- elementSize,rowSize,groupSize);
- }
- break;
- case GL_UNSIGNED_SHORT:
- if (newDepth > 1) {
- halveImage3D(cmpts,extractUshort,shoveUshort,
- newWidth,newHeight,newDepth,
- srcImage,dstImage,elementSize,groupSize,rowSize,
- imageSize,myswapBytes);
- }
- else {
- halveImage_ushort(cmpts,newWidth,newHeight,srcImage,dstImage,
- elementSize,rowSize,groupSize,myswapBytes);
- }
- break;
- case GL_SHORT:
- if (newDepth > 1) {
- halveImage3D(cmpts,extractSshort,shoveSshort,
- newWidth,newHeight,newDepth,
- srcImage,dstImage,elementSize,groupSize,rowSize,
- imageSize,myswapBytes);
- }
- else {
- halveImage_short(cmpts,newWidth,newHeight,srcImage,dstImage,
- elementSize,rowSize,groupSize,myswapBytes);
- }
- break;
- case GL_UNSIGNED_INT:
- if (newDepth > 1) {
- halveImage3D(cmpts,extractUint,shoveUint,
- newWidth,newHeight,newDepth,
- srcImage,dstImage,elementSize,groupSize,rowSize,
- imageSize,myswapBytes);
- }
- else {
- halveImage_uint(cmpts,newWidth,newHeight,srcImage,dstImage,
- elementSize,rowSize,groupSize,myswapBytes);
- }
- break;
- case GL_INT:
- if (newDepth > 1) {
- halveImage3D(cmpts,extractSint,shoveSint,
- newWidth,newHeight,newDepth,
- srcImage,dstImage,elementSize,groupSize,rowSize,
- imageSize,myswapBytes);
- }
- else {
- halveImage_int(cmpts,newWidth,newHeight,srcImage,dstImage,
- elementSize,rowSize,groupSize,myswapBytes);
- }
- break;
- case GL_FLOAT:
- if (newDepth > 1) {
- halveImage3D(cmpts,extractFloat,shoveFloat,
- newWidth,newHeight,newDepth,
- srcImage,dstImage,elementSize,groupSize,rowSize,
- imageSize,myswapBytes);
- }
- else {
- halveImage_float(cmpts,newWidth,newHeight,srcImage,dstImage,
- elementSize,rowSize,groupSize,myswapBytes);
- }
- break;
- case GL_UNSIGNED_BYTE_3_3_2:
- halveImagePackedPixel3D(3,extract332,shove332,
- newWidth,newHeight,newDepth,
- srcImage,dstImage,elementSize,rowSize,
- imageSize,myswapBytes);
- break;
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- halveImagePackedPixel3D(3,extract233rev,shove233rev,
- newWidth,newHeight,newDepth,
- srcImage,dstImage,elementSize,rowSize,
- imageSize,myswapBytes);
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- halveImagePackedPixel3D(3,extract565,shove565,
- newWidth,newHeight,newDepth,
- srcImage,dstImage,elementSize,rowSize,
- imageSize,myswapBytes);
- break;
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- halveImagePackedPixel3D(3,extract565rev,shove565rev,
- newWidth,newHeight,newDepth,
- srcImage,dstImage,elementSize,rowSize,
- imageSize,myswapBytes);
- break;
- case GL_UNSIGNED_SHORT_4_4_4_4:
- halveImagePackedPixel3D(4,extract4444,shove4444,
- newWidth,newHeight,newDepth,
- srcImage,dstImage,elementSize,rowSize,
- imageSize,myswapBytes);
- break;
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- halveImagePackedPixel3D(4,extract4444rev,shove4444rev,
- newWidth,newHeight,newDepth,
- srcImage,dstImage,elementSize,rowSize,
- imageSize,myswapBytes);
- break;
- case GL_UNSIGNED_SHORT_5_5_5_1:
- halveImagePackedPixel3D(4,extract5551,shove5551,
- newWidth,newHeight,newDepth,
- srcImage,dstImage,elementSize,rowSize,
- imageSize,myswapBytes);
- break;
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- halveImagePackedPixel3D(4,extract1555rev,shove1555rev,
- newWidth,newHeight,newDepth,
- srcImage,dstImage,elementSize,rowSize,
- imageSize,myswapBytes);
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- halveImagePackedPixel3D(4,extract8888,shove8888,
- newWidth,newHeight,newDepth,
- srcImage,dstImage,elementSize,rowSize,
- imageSize,myswapBytes);
- break;
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- halveImagePackedPixel3D(4,extract8888rev,shove8888rev,
- newWidth,newHeight,newDepth,
- srcImage,dstImage,elementSize,rowSize,
- imageSize,myswapBytes);
- break;
- case GL_UNSIGNED_INT_10_10_10_2:
- halveImagePackedPixel3D(4,extract1010102,shove1010102,
- newWidth,newHeight,newDepth,
- srcImage,dstImage,elementSize,rowSize,
- imageSize,myswapBytes);
- break;
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- halveImagePackedPixel3D(4,extract2101010rev,shove2101010rev,
- newWidth,newHeight,newDepth,
- srcImage,dstImage,elementSize,rowSize,
- imageSize,myswapBytes);
- break;
- default:
- assert(0);
- break;
- }
-
- __GLU_SWAP_IMAGE(srcImage,dstImage);
-
- if (newWidth > 1) { newWidth /= 2; rowSize /= 2;}
- if (newHeight > 1) { newHeight /= 2; imageSize = rowSize * newHeight; }
- if (newDepth > 1) newDepth /= 2;
- {
- /* call tex image with srcImage untouched since it's not padded */
- if (baseLevel <= level && level <= maxLevel) {
- gluTexImage3D(target, level, internalFormat, newWidth, newHeight,
- newDepth,0, format, type, (void *) srcImage);
- }
- }
- } /* for level */
- glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment);
- glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows);
- glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length);
- glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes);
- glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images);
- glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height);
-
- free(srcImage); /*if you get to here, a srcImage has always been malloc'ed*/
- if (dstImage) { /* if it's non-rectangular and only 1 level */
- free(dstImage);
- }
- return 0;
-} /* gluBuild3DMipmapLevelsCore() */
-
-GLint GLAPIENTRY
-gluBuild3DMipmapLevels(GLenum target, GLint internalFormat,
- GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type,
- GLint userLevel, GLint baseLevel, GLint maxLevel,
- const void *data)
-{
- int level, levels;
-
- int rc= checkMipmapArgs(internalFormat,format,type);
- if (rc != 0) return rc;
-
- if (width < 1 || height < 1 || depth < 1) {
- return GLU_INVALID_VALUE;
- }
-
- if(type == GL_BITMAP) {
- return GLU_INVALID_ENUM;
- }
-
- levels = computeLog(width);
- level = computeLog(height);
- if (level > levels) levels=level;
- level = computeLog(depth);
- if (level > levels) levels=level;
-
- levels+= userLevel;
- if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels))
- return GLU_INVALID_VALUE;
-
- return gluBuild3DMipmapLevelsCore(target, internalFormat,
- width, height, depth,
- width, height, depth,
- format, type,
- userLevel, baseLevel, maxLevel,
- data);
-} /* gluBuild3DMipmapLevels() */
-
-GLint GLAPIENTRY
-gluBuild3DMipmaps(GLenum target, GLint internalFormat,
- GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type, const void *data)
-{
- GLint widthPowerOf2, heightPowerOf2, depthPowerOf2;
- int level, levels;
-
- int rc= checkMipmapArgs(internalFormat,format,type);
- if (rc != 0) return rc;
-
- if (width < 1 || height < 1 || depth < 1) {
- return GLU_INVALID_VALUE;
- }
-
- if(type == GL_BITMAP) {
- return GLU_INVALID_ENUM;
- }
-
- closestFit3D(target,width,height,depth,internalFormat,format,type,
- &widthPowerOf2,&heightPowerOf2,&depthPowerOf2);
-
- levels = computeLog(widthPowerOf2);
- level = computeLog(heightPowerOf2);
- if (level > levels) levels=level;
- level = computeLog(depthPowerOf2);
- if (level > levels) levels=level;
-
- return gluBuild3DMipmapLevelsCore(target, internalFormat,
- width, height, depth,
- widthPowerOf2, heightPowerOf2,
- depthPowerOf2,
- format, type, 0, 0, levels,
- data);
-} /* gluBuild3DMipmaps() */
-
-static GLdouble extractUbyte(int isSwap, const void *ubyte)
-{
- isSwap= isSwap; /* turn off warnings */
-
- assert(*((const GLubyte *)ubyte) <= 255);
-
- return (GLdouble)(*((const GLubyte *)ubyte));
-} /* extractUbyte() */
-
-static void shoveUbyte(GLdouble value, int index, void *data)
-{
- assert(0.0 <= value && value < 256.0);
-
- ((GLubyte *)data)[index]= (GLubyte)value;
-} /* shoveUbyte() */
-
-static GLdouble extractSbyte(int isSwap, const void *sbyte)
-{
- isSwap= isSwap; /* turn off warnings */
-
- assert(*((const GLbyte *)sbyte) <= 127);
-
- return (GLdouble)(*((const GLbyte *)sbyte));
-} /* extractSbyte() */
-
-static void shoveSbyte(GLdouble value, int index, void *data)
-{
- ((GLbyte *)data)[index]= (GLbyte)value;
-} /* shoveSbyte() */
-
-static GLdouble extractUshort(int isSwap, const void *uitem)
-{
- GLushort ushort;
-
- if (isSwap) {
- ushort= __GLU_SWAP_2_BYTES(uitem);
- }
- else {
- ushort= *(const GLushort *)uitem;
- }
-
- assert(ushort <= 65535);
-
- return (GLdouble)ushort;
-} /* extractUshort() */
-
-static void shoveUshort(GLdouble value, int index, void *data)
-{
- assert(0.0 <= value && value < 65536.0);
-
- ((GLushort *)data)[index]= (GLushort)value;
-} /* shoveUshort() */
-
-static GLdouble extractSshort(int isSwap, const void *sitem)
-{
- GLshort sshort;
-
- if (isSwap) {
- sshort= __GLU_SWAP_2_BYTES(sitem);
- }
- else {
- sshort= *(const GLshort *)sitem;
- }
-
- assert(sshort <= 32767);
-
- return (GLdouble)sshort;
-} /* extractSshort() */
-
-static void shoveSshort(GLdouble value, int index, void *data)
-{
- assert(0.0 <= value && value < 32768.0);
-
- ((GLshort *)data)[index]= (GLshort)value;
-} /* shoveSshort() */
-
-static GLdouble extractUint(int isSwap, const void *uitem)
-{
- GLuint uint;
-
- if (isSwap) {
- uint= __GLU_SWAP_4_BYTES(uitem);
- }
- else {
- uint= *(const GLuint *)uitem;
- }
-
- assert(uint <= 0xffffffff);
-
- return (GLdouble)uint;
-} /* extractUint() */
-
-static void shoveUint(GLdouble value, int index, void *data)
-{
- assert(0.0 <= value && value <= (GLdouble) UINT_MAX);
-
- ((GLuint *)data)[index]= (GLuint)value;
-} /* shoveUint() */
-
-static GLdouble extractSint(int isSwap, const void *sitem)
-{
- GLint sint;
-
- if (isSwap) {
- sint= __GLU_SWAP_4_BYTES(sitem);
- }
- else {
- sint= *(const GLint *)sitem;
- }
-
- assert(sint <= 0x7fffffff);
-
- return (GLdouble)sint;
-} /* extractSint() */
-
-static void shoveSint(GLdouble value, int index, void *data)
-{
- assert(0.0 <= value && value <= (GLdouble) INT_MAX);
-
- ((GLint *)data)[index]= (GLint)value;
-} /* shoveSint() */
-
-static GLdouble extractFloat(int isSwap, const void *item)
-{
- GLfloat ffloat;
-
- if (isSwap) {
- ffloat= __GLU_SWAP_4_BYTES(item);
- }
- else {
- ffloat= *(const GLfloat *)item;
- }
-
- assert(ffloat <= 1.0);
-
- return (GLdouble)ffloat;
-} /* extractFloat() */
-
-static void shoveFloat(GLdouble value, int index, void *data)
-{
- assert(0.0 <= value && value <= 1.0);
-
- ((GLfloat *)data)[index]= value;
-} /* shoveFloat() */
-
-static void halveImageSlice(int components,
- GLdouble (*extract)(int, const void *),
- void (*shove)(GLdouble, int, void *),
- GLint width, GLint height, GLint depth,
- const void *dataIn, void *dataOut,
- GLint elementSizeInBytes,
- GLint groupSizeInBytes,
- GLint rowSizeInBytes,
- GLint imageSizeInBytes,
- GLint isSwap)
-{
- int ii, jj;
- int halfWidth= width / 2;
- int halfHeight= height / 2;
- int halfDepth= depth / 2;
- const char *src= (const char *)dataIn;
- int rowPadBytes= rowSizeInBytes - (width * groupSizeInBytes);
- int imagePadBytes= imageSizeInBytes - (width*height*groupSizeInBytes);
- int outIndex= 0;
-
- assert((width == 1 || height == 1) && depth >= 2);
-
- if (width == height) { /* a 1-pixel column viewed from top */
- /* printf("1-column\n");*/
- assert(width == 1 && height == 1);
- assert(depth >= 2);
-
- for (ii= 0; ii< halfDepth; ii++) {
- int cc;
-
- for (cc = 0; cc < components; cc++) {
- double totals[4];
- double extractTotals[BOX2][4];
- int kk;
-
- extractTotals[0][cc]= (*extract)(isSwap,src);
- extractTotals[1][cc]= (*extract)(isSwap,(src+imageSizeInBytes));
-
- /* average 2 pixels since only a column */
- totals[cc]= 0.0;
- /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED];
- * totals[RED]/= 2.0;
- */
- for (kk = 0; kk < BOX2; kk++) {
- totals[cc]+= extractTotals[kk][cc];
- }
- totals[cc]/= (double)BOX2;
-
- (*shove)(totals[cc],outIndex,dataOut);
- outIndex++;
- src+= elementSizeInBytes;
- } /* for cc */
-
- /* skip over to next group of 2 */
- src+= rowSizeInBytes;
- } /* for ii */
-
- assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
- assert(outIndex == halfDepth * components);
- }
- else if (height == 1) { /* horizontal slice viewed from top */
- /* printf("horizontal slice\n"); */
- assert(width != 1);
-
- for (ii= 0; ii< halfDepth; ii++) {
- for (jj= 0; jj< halfWidth; jj++) {
- int cc;
-
- for (cc = 0; cc < components; cc++) {
- int kk;
- double totals[4];
- double extractTotals[BOX4][4];
-
- extractTotals[0][cc]=(*extract)(isSwap,src);
- extractTotals[1][cc]=(*extract)(isSwap,
- (src+groupSizeInBytes));
- extractTotals[2][cc]=(*extract)(isSwap,
- (src+imageSizeInBytes));
- extractTotals[3][cc]=(*extract)(isSwap,
- (src+imageSizeInBytes+groupSizeInBytes));
-
- /* grab 4 pixels to average */
- totals[cc]= 0.0;
- /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
- * extractTotals[2][RED]+extractTotals[3][RED];
- * totals[RED]/= 4.0;
- */
- for (kk = 0; kk < BOX4; kk++) {
- totals[cc]+= extractTotals[kk][cc];
- }
- totals[cc]/= (double)BOX4;
-
- (*shove)(totals[cc],outIndex,dataOut);
- outIndex++;
-
- src+= elementSizeInBytes;
- } /* for cc */
-
- /* skip over to next horizontal square of 4 */
- src+= groupSizeInBytes;
- } /* for jj */
- src+= rowPadBytes;
-
- src+= rowSizeInBytes;
- } /* for ii */
-
- assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
- assert(outIndex == halfWidth * halfDepth * components);
- }
- else if (width == 1) { /* vertical slice viewed from top */
- /* printf("vertical slice\n"); */
- assert(height != 1);
-
- for (ii= 0; ii< halfDepth; ii++) {
- for (jj= 0; jj< halfHeight; jj++) {
- int cc;
-
- for (cc = 0; cc < components; cc++) {
- int kk;
- double totals[4];
- double extractTotals[BOX4][4];
-
- extractTotals[0][cc]=(*extract)(isSwap,src);
- extractTotals[1][cc]=(*extract)(isSwap,
- (src+rowSizeInBytes));
- extractTotals[2][cc]=(*extract)(isSwap,
- (src+imageSizeInBytes));
- extractTotals[3][cc]=(*extract)(isSwap,
- (src+imageSizeInBytes+rowSizeInBytes));
-
- /* grab 4 pixels to average */
- totals[cc]= 0.0;
- /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
- * extractTotals[2][RED]+extractTotals[3][RED];
- * totals[RED]/= 4.0;
- */
- for (kk = 0; kk < BOX4; kk++) {
- totals[cc]+= extractTotals[kk][cc];
- }
- totals[cc]/= (double)BOX4;
-
- (*shove)(totals[cc],outIndex,dataOut);
- outIndex++;
-
- src+= elementSizeInBytes;
- } /* for cc */
- src+= rowPadBytes;
-
- /* skip over to next vertical square of 4 */
- src+= rowSizeInBytes;
- } /* for jj */
- src+= imagePadBytes;
-
- src+= imageSizeInBytes;
- } /* for ii */
-
- assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
- assert(outIndex == halfHeight * halfDepth * components);
- }
-
-} /* halveImageSlice() */
-
-static void halveImage3D(int components,
- GLdouble (*extract)(int, const void *),
- void (*shove)(GLdouble, int, void *),
- GLint width, GLint height, GLint depth,
- const void *dataIn, void *dataOut,
- GLint elementSizeInBytes,
- GLint groupSizeInBytes,
- GLint rowSizeInBytes,
- GLint imageSizeInBytes,
- GLint isSwap)
-{
- assert(depth > 1);
-
- /* a horizontal/vertical/one-column slice viewed from top */
- if (width == 1 || height == 1) {
- assert(1 <= depth);
-
- halveImageSlice(components,extract,shove, width, height, depth,
- dataIn, dataOut, elementSizeInBytes, groupSizeInBytes,
- rowSizeInBytes, imageSizeInBytes, isSwap);
- return;
- }
- {
- int ii, jj, dd;
-
- int halfWidth= width / 2;
- int halfHeight= height / 2;
- int halfDepth= depth / 2;
- const char *src= (const char *) dataIn;
- int rowPadBytes= rowSizeInBytes - (width*groupSizeInBytes);
- int imagePadBytes= imageSizeInBytes - (width*height*groupSizeInBytes);
- int outIndex= 0;
-
- for (dd= 0; dd < halfDepth; dd++) {
- for (ii= 0; ii< halfHeight; ii++) {
- for (jj= 0; jj< halfWidth; jj++) {
- int cc;
-
- for (cc= 0; cc < components; cc++) {
- int kk;
-#define BOX8 8
- double totals[4]; /* 4 is maximum components */
- double extractTotals[BOX8][4]; /* 4 is maximum components */
-
- extractTotals[0][cc]= (*extract)(isSwap,src);
- extractTotals[1][cc]= (*extract)(isSwap,
- (src+groupSizeInBytes));
- extractTotals[2][cc]= (*extract)(isSwap,
- (src+rowSizeInBytes));
- extractTotals[3][cc]= (*extract)(isSwap,
- (src+rowSizeInBytes+groupSizeInBytes));
-
- extractTotals[4][cc]= (*extract)(isSwap,
- (src+imageSizeInBytes));
-
- extractTotals[5][cc]= (*extract)(isSwap,
- (src+groupSizeInBytes+imageSizeInBytes));
- extractTotals[6][cc]= (*extract)(isSwap,
- (src+rowSizeInBytes+imageSizeInBytes));
- extractTotals[7][cc]= (*extract)(isSwap,
- (src+rowSizeInBytes+groupSizeInBytes+imageSizeInBytes));
-
- totals[cc]= 0.0;
-
- /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+
- * extractTotals[2][RED]+extractTotals[3][RED]+
- * extractTotals[4][RED]+extractTotals[5][RED]+
- * extractTotals[6][RED]+extractTotals[7][RED];
- * totals[RED]/= 8.0;
- */
- for (kk = 0; kk < BOX8; kk++) {
- totals[cc]+= extractTotals[kk][cc];
- }
- totals[cc]/= (double)BOX8;
-
- (*shove)(totals[cc],outIndex,dataOut);
-
- outIndex++;
-
- src+= elementSizeInBytes; /* go to next component */
- } /* for cc */
-
- /* skip over to next square of 4 */
- src+= groupSizeInBytes;
- } /* for jj */
- /* skip past pad bytes, if any, to get to next row */
- src+= rowPadBytes;
-
- /* src is at beginning of a row here, but it's the second row of
- * the square block of 4 pixels that we just worked on so we
- * need to go one more row.
- * i.e.,
- * OO...
- * here -->OO...
- * but want -->OO...
- * OO...
- * ...
- */
- src+= rowSizeInBytes;
- } /* for ii */
-
- /* skip past pad bytes, if any, to get to next image */
- src+= imagePadBytes;
-
- src+= imageSizeInBytes;
- } /* for dd */
-
- /* both pointers must reach one byte after the end */
- assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]);
- assert(outIndex == halfWidth * halfHeight * halfDepth * components);
- }
-} /* halveImage3D() */
-
-
-
-/*** mipmap.c ***/
-
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#include "gluos.h"
-#include <math.h>
-#include <GL/gl.h>
-#include <GL/glu.h>
-#include "gluint.h"
-
-/*
-** Make m an identity matrix
-*/
-static void __gluMakeIdentityd(GLdouble m[16])
-{
- m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0;
- m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0;
- m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0;
- m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1;
-}
-
-static void __gluMakeIdentityf(GLfloat m[16])
-{
- m[0+4*0] = 1; m[0+4*1] = 0; m[0+4*2] = 0; m[0+4*3] = 0;
- m[1+4*0] = 0; m[1+4*1] = 1; m[1+4*2] = 0; m[1+4*3] = 0;
- m[2+4*0] = 0; m[2+4*1] = 0; m[2+4*2] = 1; m[2+4*3] = 0;
- m[3+4*0] = 0; m[3+4*1] = 0; m[3+4*2] = 0; m[3+4*3] = 1;
-}
-
-void GLAPIENTRY
-gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top)
-{
- glOrtho(left, right, bottom, top, -1, 1);
-}
-
-#define __glPi 3.14159265358979323846
-
-void GLAPIENTRY
-gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
-{
- GLdouble m[4][4];
- double sine, cotangent, deltaZ;
- double radians = fovy / 2 * __glPi / 180;
-
- deltaZ = zFar - zNear;
- sine = sin(radians);
- if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) {
- return;
- }
- cotangent = COS(radians) / sine;
-
- __gluMakeIdentityd(&m[0][0]);
- m[0][0] = cotangent / aspect;
- m[1][1] = cotangent;
- m[2][2] = -(zFar + zNear) / deltaZ;
- m[2][3] = -1;
- m[3][2] = -2 * zNear * zFar / deltaZ;
- m[3][3] = 0;
- glMultMatrixd(&m[0][0]);
-}
-
-static void normalize(float v[3])
-{
- float r;
-
- r = sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] );
- if (r == 0.0) return;
-
- v[0] /= r;
- v[1] /= r;
- v[2] /= r;
-}
-
-static void cross(float v1[3], float v2[3], float result[3])
-{
- result[0] = v1[1]*v2[2] - v1[2]*v2[1];
- result[1] = v1[2]*v2[0] - v1[0]*v2[2];
- result[2] = v1[0]*v2[1] - v1[1]*v2[0];
-}
-
-void GLAPIENTRY
-gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx,
- GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy,
- GLdouble upz)
-{
- float forward[3], side[3], up[3];
- GLfloat m[4][4];
-
- forward[0] = centerx - eyex;
- forward[1] = centery - eyey;
- forward[2] = centerz - eyez;
-
- up[0] = upx;
- up[1] = upy;
- up[2] = upz;
-
- normalize(forward);
-
- /* Side = forward x up */
- cross(forward, up, side);
- normalize(side);
-
- /* Recompute up as: up = side x forward */
- cross(side, forward, up);
-
- __gluMakeIdentityf(&m[0][0]);
- m[0][0] = side[0];
- m[1][0] = side[1];
- m[2][0] = side[2];
-
- m[0][1] = up[0];
- m[1][1] = up[1];
- m[2][1] = up[2];
-
- m[0][2] = -forward[0];
- m[1][2] = -forward[1];
- m[2][2] = -forward[2];
-
- glMultMatrixf(&m[0][0]);
- glTranslated(-eyex, -eyey, -eyez);
-}
-
-static void __gluMultMatrixVecd(const GLdouble matrix[16], const GLdouble in[4],
- GLdouble out[4])
-{
- int i;
-
- for (i=0; i<4; i++) {
- out[i] =
- in[0] * matrix[0*4+i] +
- in[1] * matrix[1*4+i] +
- in[2] * matrix[2*4+i] +
- in[3] * matrix[3*4+i];
- }
-}
-
-/*
-** Invert 4x4 matrix.
-** Contributed by David Moore (See Mesa bug #6748)
-*/
-static int __gluInvertMatrixd(const GLdouble m[16], GLdouble invOut[16])
-{
- double inv[16], det;
- int i;
-
- inv[0] = m[5]*m[10]*m[15] - m[5]*m[11]*m[14] - m[9]*m[6]*m[15]
- + m[9]*m[7]*m[14] + m[13]*m[6]*m[11] - m[13]*m[7]*m[10];
- inv[4] = -m[4]*m[10]*m[15] + m[4]*m[11]*m[14] + m[8]*m[6]*m[15]
- - m[8]*m[7]*m[14] - m[12]*m[6]*m[11] + m[12]*m[7]*m[10];
- inv[8] = m[4]*m[9]*m[15] - m[4]*m[11]*m[13] - m[8]*m[5]*m[15]
- + m[8]*m[7]*m[13] + m[12]*m[5]*m[11] - m[12]*m[7]*m[9];
- inv[12] = -m[4]*m[9]*m[14] + m[4]*m[10]*m[13] + m[8]*m[5]*m[14]
- - m[8]*m[6]*m[13] - m[12]*m[5]*m[10] + m[12]*m[6]*m[9];
- inv[1] = -m[1]*m[10]*m[15] + m[1]*m[11]*m[14] + m[9]*m[2]*m[15]
- - m[9]*m[3]*m[14] - m[13]*m[2]*m[11] + m[13]*m[3]*m[10];
- inv[5] = m[0]*m[10]*m[15] - m[0]*m[11]*m[14] - m[8]*m[2]*m[15]
- + m[8]*m[3]*m[14] + m[12]*m[2]*m[11] - m[12]*m[3]*m[10];
- inv[9] = -m[0]*m[9]*m[15] + m[0]*m[11]*m[13] + m[8]*m[1]*m[15]
- - m[8]*m[3]*m[13] - m[12]*m[1]*m[11] + m[12]*m[3]*m[9];
- inv[13] = m[0]*m[9]*m[14] - m[0]*m[10]*m[13] - m[8]*m[1]*m[14]
- + m[8]*m[2]*m[13] + m[12]*m[1]*m[10] - m[12]*m[2]*m[9];
- inv[2] = m[1]*m[6]*m[15] - m[1]*m[7]*m[14] - m[5]*m[2]*m[15]
- + m[5]*m[3]*m[14] + m[13]*m[2]*m[7] - m[13]*m[3]*m[6];
- inv[6] = -m[0]*m[6]*m[15] + m[0]*m[7]*m[14] + m[4]*m[2]*m[15]
- - m[4]*m[3]*m[14] - m[12]*m[2]*m[7] + m[12]*m[3]*m[6];
- inv[10] = m[0]*m[5]*m[15] - m[0]*m[7]*m[13] - m[4]*m[1]*m[15]
- + m[4]*m[3]*m[13] + m[12]*m[1]*m[7] - m[12]*m[3]*m[5];
- inv[14] = -m[0]*m[5]*m[14] + m[0]*m[6]*m[13] + m[4]*m[1]*m[14]
- - m[4]*m[2]*m[13] - m[12]*m[1]*m[6] + m[12]*m[2]*m[5];
- inv[3] = -m[1]*m[6]*m[11] + m[1]*m[7]*m[10] + m[5]*m[2]*m[11]
- - m[5]*m[3]*m[10] - m[9]*m[2]*m[7] + m[9]*m[3]*m[6];
- inv[7] = m[0]*m[6]*m[11] - m[0]*m[7]*m[10] - m[4]*m[2]*m[11]
- + m[4]*m[3]*m[10] + m[8]*m[2]*m[7] - m[8]*m[3]*m[6];
- inv[11] = -m[0]*m[5]*m[11] + m[0]*m[7]*m[9] + m[4]*m[1]*m[11]
- - m[4]*m[3]*m[9] - m[8]*m[1]*m[7] + m[8]*m[3]*m[5];
- inv[15] = m[0]*m[5]*m[10] - m[0]*m[6]*m[9] - m[4]*m[1]*m[10]
- + m[4]*m[2]*m[9] + m[8]*m[1]*m[6] - m[8]*m[2]*m[5];
-
- det = m[0]*inv[0] + m[1]*inv[4] + m[2]*inv[8] + m[3]*inv[12];
- if (det == 0)
- return GL_FALSE;
-
- det = 1.0 / det;
-
- for (i = 0; i < 16; i++)
- invOut[i] = inv[i] * det;
-
- return GL_TRUE;
-}
-
-static void __gluMultMatricesd(const GLdouble a[16], const GLdouble b[16],
- GLdouble r[16])
-{
- int i, j;
-
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- r[i*4+j] =
- a[i*4+0]*b[0*4+j] +
- a[i*4+1]*b[1*4+j] +
- a[i*4+2]*b[2*4+j] +
- a[i*4+3]*b[3*4+j];
- }
- }
-}
-
-GLint GLAPIENTRY
-gluProject(GLdouble objx, GLdouble objy, GLdouble objz,
- const GLdouble modelMatrix[16],
- const GLdouble projMatrix[16],
- const GLint viewport[4],
- GLdouble *winx, GLdouble *winy, GLdouble *winz)
-{
- double in[4];
- double out[4];
-
- in[0]=objx;
- in[1]=objy;
- in[2]=objz;
- in[3]=1.0;
- __gluMultMatrixVecd(modelMatrix, in, out);
- __gluMultMatrixVecd(projMatrix, out, in);
- if (in[3] == 0.0) return(GL_FALSE);
- in[0] /= in[3];
- in[1] /= in[3];
- in[2] /= in[3];
- /* Map x, y and z to range 0-1 */
- in[0] = in[0] * 0.5 + 0.5;
- in[1] = in[1] * 0.5 + 0.5;
- in[2] = in[2] * 0.5 + 0.5;
-
- /* Map x,y to viewport */
- in[0] = in[0] * viewport[2] + viewport[0];
- in[1] = in[1] * viewport[3] + viewport[1];
-
- *winx=in[0];
- *winy=in[1];
- *winz=in[2];
- return(GL_TRUE);
-}
-
-GLint GLAPIENTRY
-gluUnProject(GLdouble winx, GLdouble winy, GLdouble winz,
- const GLdouble modelMatrix[16],
- const GLdouble projMatrix[16],
- const GLint viewport[4],
- GLdouble *objx, GLdouble *objy, GLdouble *objz)
-{
- double finalMatrix[16];
- double in[4];
- double out[4];
-
- __gluMultMatricesd(modelMatrix, projMatrix, finalMatrix);
- if (!__gluInvertMatrixd(finalMatrix, finalMatrix)) return(GL_FALSE);
-
- in[0]=winx;
- in[1]=winy;
- in[2]=winz;
- in[3]=1.0;
-
- /* Map x and y from window coordinates */
- in[0] = (in[0] - viewport[0]) / viewport[2];
- in[1] = (in[1] - viewport[1]) / viewport[3];
-
- /* Map to range -1 to 1 */
- in[0] = in[0] * 2 - 1;
- in[1] = in[1] * 2 - 1;
- in[2] = in[2] * 2 - 1;
-
- __gluMultMatrixVecd(finalMatrix, in, out);
- if (out[3] == 0.0) return(GL_FALSE);
- out[0] /= out[3];
- out[1] /= out[3];
- out[2] /= out[3];
- *objx = out[0];
- *objy = out[1];
- *objz = out[2];
- return(GL_TRUE);
-}
-
-GLint GLAPIENTRY
-gluUnProject4(GLdouble winx, GLdouble winy, GLdouble winz, GLdouble clipw,
- const GLdouble modelMatrix[16],
- const GLdouble projMatrix[16],
- const GLint viewport[4],
- GLclampd nearVal, GLclampd farVal,
- GLdouble *objx, GLdouble *objy, GLdouble *objz,
- GLdouble *objw)
-{
- double finalMatrix[16];
- double in[4];
- double out[4];
-
- __gluMultMatricesd(modelMatrix, projMatrix, finalMatrix);
- if (!__gluInvertMatrixd(finalMatrix, finalMatrix)) return(GL_FALSE);
-
- in[0]=winx;
- in[1]=winy;
- in[2]=winz;
- in[3]=clipw;
-
- /* Map x and y from window coordinates */
- in[0] = (in[0] - viewport[0]) / viewport[2];
- in[1] = (in[1] - viewport[1]) / viewport[3];
- in[2] = (in[2] - nearVal) / (farVal - nearVal);
-
- /* Map to range -1 to 1 */
- in[0] = in[0] * 2 - 1;
- in[1] = in[1] * 2 - 1;
- in[2] = in[2] * 2 - 1;
-
- __gluMultMatrixVecd(finalMatrix, in, out);
- if (out[3] == 0.0) return(GL_FALSE);
- *objx = out[0];
- *objy = out[1];
- *objz = out[2];
- *objw = out[3];
- return(GL_TRUE);
-}
-
-void GLAPIENTRY
-gluPickMatrix(GLdouble x, GLdouble y, GLdouble deltax, GLdouble deltay,
- GLint viewport[4])
-{
- if (deltax <= 0 || deltay <= 0) {
- return;
- }
-
- /* Translate and scale the picked region to the entire window */
- glTranslatef((viewport[2] - 2 * (x - viewport[0])) / deltax,
- (viewport[3] - 2 * (y - viewport[1])) / deltay, 0);
- glScalef(viewport[2] / deltax, viewport[3] / deltay, 1.0);
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#include "gluos.h"
-#include "gluint.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <GL/gl.h>
-#include <GL/glu.h>
-
-/* Make it not a power of two to avoid cache thrashing on the chip */
-#define CACHE_SIZE 240
-
-#undef PI
-#define PI 3.14159265358979323846
-
-struct GLUquadric {
- GLint normals;
- GLboolean textureCoords;
- GLint orientation;
- GLint drawStyle;
- void (GLAPIENTRY *errorCallback)( GLint );
-};
-
-GLUquadric * GLAPIENTRY
-gluNewQuadric(void)
-{
- GLUquadric *newstate;
-
- newstate = (GLUquadric *) malloc(sizeof(GLUquadric));
- if (newstate == NULL) {
- /* Can't report an error at this point... */
- return NULL;
- }
- newstate->normals = GLU_SMOOTH;
- newstate->textureCoords = GL_FALSE;
- newstate->orientation = GLU_OUTSIDE;
- newstate->drawStyle = GLU_FILL;
- newstate->errorCallback = NULL;
- return newstate;
-}
-
-
-void GLAPIENTRY
-gluDeleteQuadric(GLUquadric *state)
-{
- free(state);
-}
-
-static void gluQuadricError(GLUquadric *qobj, GLenum which)
-{
- if (qobj->errorCallback) {
- qobj->errorCallback(which);
- }
-}
-
-void GLAPIENTRY
-gluQuadricCallback(GLUquadric *qobj, GLenum which, _GLUfuncptr fn)
-{
- switch (which) {
- case GLU_ERROR:
- qobj->errorCallback = (void (GLAPIENTRY *)(GLint)) fn;
- break;
- default:
- gluQuadricError(qobj, GLU_INVALID_ENUM);
- return;
- }
-}
-
-void GLAPIENTRY
-gluQuadricNormals(GLUquadric *qobj, GLenum normals)
-{
- switch (normals) {
- case GLU_SMOOTH:
- case GLU_FLAT:
- case GLU_NONE:
- break;
- default:
- gluQuadricError(qobj, GLU_INVALID_ENUM);
- return;
- }
- qobj->normals = normals;
-}
-
-void GLAPIENTRY
-gluQuadricTexture(GLUquadric *qobj, GLboolean textureCoords)
-{
- qobj->textureCoords = textureCoords;
-}
-
-void GLAPIENTRY
-gluQuadricOrientation(GLUquadric *qobj, GLenum orientation)
-{
- switch(orientation) {
- case GLU_OUTSIDE:
- case GLU_INSIDE:
- break;
- default:
- gluQuadricError(qobj, GLU_INVALID_ENUM);
- return;
- }
- qobj->orientation = orientation;
-}
-
-void GLAPIENTRY
-gluQuadricDrawStyle(GLUquadric *qobj, GLenum drawStyle)
-{
- switch(drawStyle) {
- case GLU_POINT:
- case GLU_LINE:
- case GLU_FILL:
- case GLU_SILHOUETTE:
- break;
- default:
- gluQuadricError(qobj, GLU_INVALID_ENUM);
- return;
- }
- qobj->drawStyle = drawStyle;
-}
-
-void GLAPIENTRY
-gluCylinder(GLUquadric *qobj, GLdouble baseRadius, GLdouble topRadius,
- GLdouble height, GLint slices, GLint stacks)
-{
- GLint i,j;
- GLfloat sinCache[CACHE_SIZE];
- GLfloat cosCache[CACHE_SIZE];
- GLfloat sinCache2[CACHE_SIZE];
- GLfloat cosCache2[CACHE_SIZE];
- GLfloat sinCache3[CACHE_SIZE];
- GLfloat cosCache3[CACHE_SIZE];
- GLfloat angle;
- GLfloat zLow, zHigh;
- GLfloat sintemp, costemp;
- GLfloat length;
- GLfloat deltaRadius;
- GLfloat zNormal;
- GLfloat xyNormalRatio;
- GLfloat radiusLow, radiusHigh;
- int needCache2, needCache3;
-
- if (slices >= CACHE_SIZE) slices = CACHE_SIZE-1;
-
- if (slices < 2 || stacks < 1 || baseRadius < 0.0 || topRadius < 0.0 ||
- height < 0.0) {
- gluQuadricError(qobj, GLU_INVALID_VALUE);
- return;
- }
-
- /* Compute length (needed for normal calculations) */
- deltaRadius = baseRadius - topRadius;
- length = SQRT(deltaRadius*deltaRadius + height*height);
- if (length == 0.0) {
- gluQuadricError(qobj, GLU_INVALID_VALUE);
- return;
- }
-
- /* Cache is the vertex locations cache */
- /* Cache2 is the various normals at the vertices themselves */
- /* Cache3 is the various normals for the faces */
- needCache2 = needCache3 = 0;
- if (qobj->normals == GLU_SMOOTH) {
- needCache2 = 1;
- }
-
- if (qobj->normals == GLU_FLAT) {
- if (qobj->drawStyle != GLU_POINT) {
- needCache3 = 1;
- }
- if (qobj->drawStyle == GLU_LINE) {
- needCache2 = 1;
- }
- }
-
- zNormal = deltaRadius / length;
- xyNormalRatio = height / length;
-
- for (i = 0; i < slices; i++) {
- angle = 2 * PI * i / slices;
- if (needCache2) {
- if (qobj->orientation == GLU_OUTSIDE) {
- sinCache2[i] = xyNormalRatio * SIN(angle);
- cosCache2[i] = xyNormalRatio * COS(angle);
- } else {
- sinCache2[i] = -xyNormalRatio * SIN(angle);
- cosCache2[i] = -xyNormalRatio * COS(angle);
- }
- }
- sinCache[i] = SIN(angle);
- cosCache[i] = COS(angle);
- }
-
- if (needCache3) {
- for (i = 0; i < slices; i++) {
- angle = 2 * PI * (i-0.5) / slices;
- if (qobj->orientation == GLU_OUTSIDE) {
- sinCache3[i] = xyNormalRatio * SIN(angle);
- cosCache3[i] = xyNormalRatio * COS(angle);
- } else {
- sinCache3[i] = -xyNormalRatio * SIN(angle);
- cosCache3[i] = -xyNormalRatio * COS(angle);
- }
- }
- }
-
- sinCache[slices] = sinCache[0];
- cosCache[slices] = cosCache[0];
- if (needCache2) {
- sinCache2[slices] = sinCache2[0];
- cosCache2[slices] = cosCache2[0];
- }
- if (needCache3) {
- sinCache3[slices] = sinCache3[0];
- cosCache3[slices] = cosCache3[0];
- }
-
- switch (qobj->drawStyle) {
- case GLU_FILL:
- /* Note:
- ** An argument could be made for using a TRIANGLE_FAN for the end
- ** of the cylinder of either radii is 0.0 (a cone). However, a
- ** TRIANGLE_FAN would not work in smooth shading mode (the common
- ** case) because the normal for the apex is different for every
- ** triangle (and TRIANGLE_FAN doesn't let me respecify that normal).
- ** Now, my choice is GL_TRIANGLES, or leave the GL_QUAD_STRIP and
- ** just let the GL trivially reject one of the two triangles of the
- ** QUAD. GL_QUAD_STRIP is probably faster, so I will leave this code
- ** alone.
- */
- for (j = 0; j < stacks; j++) {
- zLow = j * height / stacks;
- zHigh = (j + 1) * height / stacks;
- radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
- radiusHigh = baseRadius - deltaRadius * ((float) (j + 1) / stacks);
-
- glBegin(GL_QUAD_STRIP);
- for (i = 0; i <= slices; i++) {
- switch(qobj->normals) {
- case GLU_FLAT:
- glNormal3f(sinCache3[i], cosCache3[i], zNormal);
- break;
- case GLU_SMOOTH:
- glNormal3f(sinCache2[i], cosCache2[i], zNormal);
- break;
- case GLU_NONE:
- default:
- break;
- }
- if (qobj->orientation == GLU_OUTSIDE) {
- if (qobj->textureCoords) {
- glTexCoord2f(1 - (float) i / slices,
- (float) j / stacks);
- }
- glVertex3f(radiusLow * sinCache[i],
- radiusLow * cosCache[i], zLow);
- if (qobj->textureCoords) {
- glTexCoord2f(1 - (float) i / slices,
- (float) (j+1) / stacks);
- }
- glVertex3f(radiusHigh * sinCache[i],
- radiusHigh * cosCache[i], zHigh);
- } else {
- if (qobj->textureCoords) {
- glTexCoord2f(1 - (float) i / slices,
- (float) (j+1) / stacks);
- }
- glVertex3f(radiusHigh * sinCache[i],
- radiusHigh * cosCache[i], zHigh);
- if (qobj->textureCoords) {
- glTexCoord2f(1 - (float) i / slices,
- (float) j / stacks);
- }
- glVertex3f(radiusLow * sinCache[i],
- radiusLow * cosCache[i], zLow);
- }
- }
- glEnd();
- }
- break;
- case GLU_POINT:
- glBegin(GL_POINTS);
- for (i = 0; i < slices; i++) {
- switch(qobj->normals) {
- case GLU_FLAT:
- case GLU_SMOOTH:
- glNormal3f(sinCache2[i], cosCache2[i], zNormal);
- break;
- case GLU_NONE:
- default:
- break;
- }
- sintemp = sinCache[i];
- costemp = cosCache[i];
- for (j = 0; j <= stacks; j++) {
- zLow = j * height / stacks;
- radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
-
- if (qobj->textureCoords) {
- glTexCoord2f(1 - (float) i / slices,
- (float) j / stacks);
- }
- glVertex3f(radiusLow * sintemp,
- radiusLow * costemp, zLow);
- }
- }
- glEnd();
- break;
- case GLU_LINE:
- for (j = 1; j < stacks; j++) {
- zLow = j * height / stacks;
- radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
-
- glBegin(GL_LINE_STRIP);
- for (i = 0; i <= slices; i++) {
- switch(qobj->normals) {
- case GLU_FLAT:
- glNormal3f(sinCache3[i], cosCache3[i], zNormal);
- break;
- case GLU_SMOOTH:
- glNormal3f(sinCache2[i], cosCache2[i], zNormal);
- break;
- case GLU_NONE:
- default:
- break;
- }
- if (qobj->textureCoords) {
- glTexCoord2f(1 - (float) i / slices,
- (float) j / stacks);
- }
- glVertex3f(radiusLow * sinCache[i],
- radiusLow * cosCache[i], zLow);
- }
- glEnd();
- }
- /* Intentionally fall through here... */
- case GLU_SILHOUETTE:
- for (j = 0; j <= stacks; j += stacks) {
- zLow = j * height / stacks;
- radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
-
- glBegin(GL_LINE_STRIP);
- for (i = 0; i <= slices; i++) {
- switch(qobj->normals) {
- case GLU_FLAT:
- glNormal3f(sinCache3[i], cosCache3[i], zNormal);
- break;
- case GLU_SMOOTH:
- glNormal3f(sinCache2[i], cosCache2[i], zNormal);
- break;
- case GLU_NONE:
- default:
- break;
- }
- if (qobj->textureCoords) {
- glTexCoord2f(1 - (float) i / slices,
- (float) j / stacks);
- }
- glVertex3f(radiusLow * sinCache[i], radiusLow * cosCache[i],
- zLow);
- }
- glEnd();
- }
- for (i = 0; i < slices; i++) {
- switch(qobj->normals) {
- case GLU_FLAT:
- case GLU_SMOOTH:
- glNormal3f(sinCache2[i], cosCache2[i], 0.0);
- break;
- case GLU_NONE:
- default:
- break;
- }
- sintemp = sinCache[i];
- costemp = cosCache[i];
- glBegin(GL_LINE_STRIP);
- for (j = 0; j <= stacks; j++) {
- zLow = j * height / stacks;
- radiusLow = baseRadius - deltaRadius * ((float) j / stacks);
-
- if (qobj->textureCoords) {
- glTexCoord2f(1 - (float) i / slices,
- (float) j / stacks);
- }
- glVertex3f(radiusLow * sintemp,
- radiusLow * costemp, zLow);
- }
- glEnd();
- }
- break;
- default:
- break;
- }
-}
-
-void GLAPIENTRY
-gluDisk(GLUquadric *qobj, GLdouble innerRadius, GLdouble outerRadius,
- GLint slices, GLint loops)
-{
- gluPartialDisk(qobj, innerRadius, outerRadius, slices, loops, 0.0, 360.0);
-}
-
-void GLAPIENTRY
-gluPartialDisk(GLUquadric *qobj, GLdouble innerRadius,
- GLdouble outerRadius, GLint slices, GLint loops,
- GLdouble startAngle, GLdouble sweepAngle)
-{
- GLint i,j;
- GLfloat sinCache[CACHE_SIZE];
- GLfloat cosCache[CACHE_SIZE];
- GLfloat angle;
- GLfloat sintemp, costemp;
- GLfloat deltaRadius;
- GLfloat radiusLow, radiusHigh;
- GLfloat texLow = 0.0, texHigh = 0.0;
- GLfloat angleOffset;
- GLint slices2;
- GLint finish;
-
- if (slices >= CACHE_SIZE) slices = CACHE_SIZE-1;
- if (slices < 2 || loops < 1 || outerRadius <= 0.0 || innerRadius < 0.0 ||
- innerRadius > outerRadius) {
- gluQuadricError(qobj, GLU_INVALID_VALUE);
- return;
- }
-
- if (sweepAngle < -360.0) sweepAngle = 360.0;
- if (sweepAngle > 360.0) sweepAngle = 360.0;
- if (sweepAngle < 0) {
- startAngle += sweepAngle;
- sweepAngle = -sweepAngle;
- }
-
- if (sweepAngle == 360.0) {
- slices2 = slices;
- } else {
- slices2 = slices + 1;
- }
-
- /* Compute length (needed for normal calculations) */
- deltaRadius = outerRadius - innerRadius;
-
- /* Cache is the vertex locations cache */
-
- angleOffset = startAngle / 180.0 * PI;
- for (i = 0; i <= slices; i++) {
- angle = angleOffset + ((PI * sweepAngle) / 180.0) * i / slices;
- sinCache[i] = SIN(angle);
- cosCache[i] = COS(angle);
- }
-
- if (sweepAngle == 360.0) {
- sinCache[slices] = sinCache[0];
- cosCache[slices] = cosCache[0];
- }
-
- switch(qobj->normals) {
- case GLU_FLAT:
- case GLU_SMOOTH:
- if (qobj->orientation == GLU_OUTSIDE) {
- glNormal3f(0.0, 0.0, 1.0);
- } else {
- glNormal3f(0.0, 0.0, -1.0);
- }
- break;
- default:
- case GLU_NONE:
- break;
- }
-
- switch (qobj->drawStyle) {
- case GLU_FILL:
- if (innerRadius == 0.0) {
- finish = loops - 1;
- /* Triangle strip for inner polygons */
- glBegin(GL_TRIANGLE_FAN);
- if (qobj->textureCoords) {
- glTexCoord2f(0.5, 0.5);
- }
- glVertex3f(0.0, 0.0, 0.0);
- radiusLow = outerRadius -
- deltaRadius * ((float) (loops-1) / loops);
- if (qobj->textureCoords) {
- texLow = radiusLow / outerRadius / 2;
- }
-
- if (qobj->orientation == GLU_OUTSIDE) {
- for (i = slices; i >= 0; i--) {
- if (qobj->textureCoords) {
- glTexCoord2f(texLow * sinCache[i] + 0.5,
- texLow * cosCache[i] + 0.5);
- }
- glVertex3f(radiusLow * sinCache[i],
- radiusLow * cosCache[i], 0.0);
- }
- } else {
- for (i = 0; i <= slices; i++) {
- if (qobj->textureCoords) {
- glTexCoord2f(texLow * sinCache[i] + 0.5,
- texLow * cosCache[i] + 0.5);
- }
- glVertex3f(radiusLow * sinCache[i],
- radiusLow * cosCache[i], 0.0);
- }
- }
- glEnd();
- } else {
- finish = loops;
- }
- for (j = 0; j < finish; j++) {
- radiusLow = outerRadius - deltaRadius * ((float) j / loops);
- radiusHigh = outerRadius - deltaRadius * ((float) (j + 1) / loops);
- if (qobj->textureCoords) {
- texLow = radiusLow / outerRadius / 2;
- texHigh = radiusHigh / outerRadius / 2;
- }
-
- glBegin(GL_QUAD_STRIP);
- for (i = 0; i <= slices; i++) {
- if (qobj->orientation == GLU_OUTSIDE) {
- if (qobj->textureCoords) {
- glTexCoord2f(texLow * sinCache[i] + 0.5,
- texLow * cosCache[i] + 0.5);
- }
- glVertex3f(radiusLow * sinCache[i],
- radiusLow * cosCache[i], 0.0);
-
- if (qobj->textureCoords) {
- glTexCoord2f(texHigh * sinCache[i] + 0.5,
- texHigh * cosCache[i] + 0.5);
- }
- glVertex3f(radiusHigh * sinCache[i],
- radiusHigh * cosCache[i], 0.0);
- } else {
- if (qobj->textureCoords) {
- glTexCoord2f(texHigh * sinCache[i] + 0.5,
- texHigh * cosCache[i] + 0.5);
- }
- glVertex3f(radiusHigh * sinCache[i],
- radiusHigh * cosCache[i], 0.0);
-
- if (qobj->textureCoords) {
- glTexCoord2f(texLow * sinCache[i] + 0.5,
- texLow * cosCache[i] + 0.5);
- }
- glVertex3f(radiusLow * sinCache[i],
- radiusLow * cosCache[i], 0.0);
- }
- }
- glEnd();
- }
- break;
- case GLU_POINT:
- glBegin(GL_POINTS);
- for (i = 0; i < slices2; i++) {
- sintemp = sinCache[i];
- costemp = cosCache[i];
- for (j = 0; j <= loops; j++) {
- radiusLow = outerRadius - deltaRadius * ((float) j / loops);
-
- if (qobj->textureCoords) {
- texLow = radiusLow / outerRadius / 2;
-
- glTexCoord2f(texLow * sinCache[i] + 0.5,
- texLow * cosCache[i] + 0.5);
- }
- glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0);
- }
- }
- glEnd();
- break;
- case GLU_LINE:
- if (innerRadius == outerRadius) {
- glBegin(GL_LINE_STRIP);
-
- for (i = 0; i <= slices; i++) {
- if (qobj->textureCoords) {
- glTexCoord2f(sinCache[i] / 2 + 0.5,
- cosCache[i] / 2 + 0.5);
- }
- glVertex3f(innerRadius * sinCache[i],
- innerRadius * cosCache[i], 0.0);
- }
- glEnd();
- break;
- }
- for (j = 0; j <= loops; j++) {
- radiusLow = outerRadius - deltaRadius * ((float) j / loops);
- if (qobj->textureCoords) {
- texLow = radiusLow / outerRadius / 2;
- }
-
- glBegin(GL_LINE_STRIP);
- for (i = 0; i <= slices; i++) {
- if (qobj->textureCoords) {
- glTexCoord2f(texLow * sinCache[i] + 0.5,
- texLow * cosCache[i] + 0.5);
- }
- glVertex3f(radiusLow * sinCache[i],
- radiusLow * cosCache[i], 0.0);
- }
- glEnd();
- }
- for (i=0; i < slices2; i++) {
- sintemp = sinCache[i];
- costemp = cosCache[i];
- glBegin(GL_LINE_STRIP);
- for (j = 0; j <= loops; j++) {
- radiusLow = outerRadius - deltaRadius * ((float) j / loops);
- if (qobj->textureCoords) {
- texLow = radiusLow / outerRadius / 2;
- }
-
- if (qobj->textureCoords) {
- glTexCoord2f(texLow * sinCache[i] + 0.5,
- texLow * cosCache[i] + 0.5);
- }
- glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0);
- }
- glEnd();
- }
- break;
- case GLU_SILHOUETTE:
- if (sweepAngle < 360.0) {
- for (i = 0; i <= slices; i+= slices) {
- sintemp = sinCache[i];
- costemp = cosCache[i];
- glBegin(GL_LINE_STRIP);
- for (j = 0; j <= loops; j++) {
- radiusLow = outerRadius - deltaRadius * ((float) j / loops);
-
- if (qobj->textureCoords) {
- texLow = radiusLow / outerRadius / 2;
- glTexCoord2f(texLow * sinCache[i] + 0.5,
- texLow * cosCache[i] + 0.5);
- }
- glVertex3f(radiusLow * sintemp, radiusLow * costemp, 0.0);
- }
- glEnd();
- }
- }
- for (j = 0; j <= loops; j += loops) {
- radiusLow = outerRadius - deltaRadius * ((float) j / loops);
- if (qobj->textureCoords) {
- texLow = radiusLow / outerRadius / 2;
- }
-
- glBegin(GL_LINE_STRIP);
- for (i = 0; i <= slices; i++) {
- if (qobj->textureCoords) {
- glTexCoord2f(texLow * sinCache[i] + 0.5,
- texLow * cosCache[i] + 0.5);
- }
- glVertex3f(radiusLow * sinCache[i],
- radiusLow * cosCache[i], 0.0);
- }
- glEnd();
- if (innerRadius == outerRadius) break;
- }
- break;
- default:
- break;
- }
-}
-
-void GLAPIENTRY
-gluSphere(GLUquadric *qobj, GLdouble radius, GLint slices, GLint stacks)
-{
- GLint i,j;
- GLfloat sinCache1a[CACHE_SIZE];
- GLfloat cosCache1a[CACHE_SIZE];
- GLfloat sinCache2a[CACHE_SIZE];
- GLfloat cosCache2a[CACHE_SIZE];
- GLfloat sinCache3a[CACHE_SIZE];
- GLfloat cosCache3a[CACHE_SIZE];
- GLfloat sinCache1b[CACHE_SIZE];
- GLfloat cosCache1b[CACHE_SIZE];
- GLfloat sinCache2b[CACHE_SIZE];
- GLfloat cosCache2b[CACHE_SIZE];
- GLfloat sinCache3b[CACHE_SIZE];
- GLfloat cosCache3b[CACHE_SIZE];
- GLfloat angle;
- GLfloat zLow, zHigh;
- GLfloat sintemp1 = 0.0, sintemp2 = 0.0, sintemp3 = 0.0, sintemp4 = 0.0;
- GLfloat costemp1 = 0.0, costemp2 = 0.0, costemp3 = 0.0, costemp4 = 0.0;
- GLboolean needCache2, needCache3;
- GLint start, finish;
-
- if (slices >= CACHE_SIZE) slices = CACHE_SIZE-1;
- if (stacks >= CACHE_SIZE) stacks = CACHE_SIZE-1;
- if (slices < 2 || stacks < 1 || radius < 0.0) {
- gluQuadricError(qobj, GLU_INVALID_VALUE);
- return;
- }
-
- /* Cache is the vertex locations cache */
- /* Cache2 is the various normals at the vertices themselves */
- /* Cache3 is the various normals for the faces */
- needCache2 = needCache3 = GL_FALSE;
-
- if (qobj->normals == GLU_SMOOTH) {
- needCache2 = GL_TRUE;
- }
-
- if (qobj->normals == GLU_FLAT) {
- if (qobj->drawStyle != GLU_POINT) {
- needCache3 = GL_TRUE;
- }
- if (qobj->drawStyle == GLU_LINE) {
- needCache2 = GL_TRUE;
- }
- }
-
- for (i = 0; i < slices; i++) {
- angle = 2 * PI * i / slices;
- sinCache1a[i] = SIN(angle);
- cosCache1a[i] = COS(angle);
- if (needCache2) {
- sinCache2a[i] = sinCache1a[i];
- cosCache2a[i] = cosCache1a[i];
- }
- }
-
- for (j = 0; j <= stacks; j++) {
- angle = PI * j / stacks;
- if (needCache2) {
- if (qobj->orientation == GLU_OUTSIDE) {
- sinCache2b[j] = SIN(angle);
- cosCache2b[j] = COS(angle);
- } else {
- sinCache2b[j] = -SIN(angle);
- cosCache2b[j] = -COS(angle);
- }
- }
- sinCache1b[j] = radius * SIN(angle);
- cosCache1b[j] = radius * COS(angle);
- }
- /* Make sure it comes to a point */
- sinCache1b[0] = 0;
- sinCache1b[stacks] = 0;
-
- if (needCache3) {
- for (i = 0; i < slices; i++) {
- angle = 2 * PI * (i-0.5) / slices;
- sinCache3a[i] = SIN(angle);
- cosCache3a[i] = COS(angle);
- }
- for (j = 0; j <= stacks; j++) {
- angle = PI * (j - 0.5) / stacks;
- if (qobj->orientation == GLU_OUTSIDE) {
- sinCache3b[j] = SIN(angle);
- cosCache3b[j] = COS(angle);
- } else {
- sinCache3b[j] = -SIN(angle);
- cosCache3b[j] = -COS(angle);
- }
- }
- }
-
- sinCache1a[slices] = sinCache1a[0];
- cosCache1a[slices] = cosCache1a[0];
- if (needCache2) {
- sinCache2a[slices] = sinCache2a[0];
- cosCache2a[slices] = cosCache2a[0];
- }
- if (needCache3) {
- sinCache3a[slices] = sinCache3a[0];
- cosCache3a[slices] = cosCache3a[0];
- }
-
- switch (qobj->drawStyle) {
- case GLU_FILL:
- /* Do ends of sphere as TRIANGLE_FAN's (if not texturing)
- ** We don't do it when texturing because we need to respecify the
- ** texture coordinates of the apex for every adjacent vertex (because
- ** it isn't a constant for that point)
- */
- if (!(qobj->textureCoords)) {
- start = 1;
- finish = stacks - 1;
-
- /* Low end first (j == 0 iteration) */
- sintemp2 = sinCache1b[1];
- zHigh = cosCache1b[1];
- switch(qobj->normals) {
- case GLU_FLAT:
- sintemp3 = sinCache3b[1];
- costemp3 = cosCache3b[1];
- break;
- case GLU_SMOOTH:
- sintemp3 = sinCache2b[1];
- costemp3 = cosCache2b[1];
- glNormal3f(sinCache2a[0] * sinCache2b[0],
- cosCache2a[0] * sinCache2b[0],
- cosCache2b[0]);
- break;
- default:
- break;
- }
- glBegin(GL_TRIANGLE_FAN);
- glVertex3f(0.0, 0.0, radius);
- if (qobj->orientation == GLU_OUTSIDE) {
- for (i = slices; i >= 0; i--) {
- switch(qobj->normals) {
- case GLU_SMOOTH:
- glNormal3f(sinCache2a[i] * sintemp3,
- cosCache2a[i] * sintemp3,
- costemp3);
- break;
- case GLU_FLAT:
- if (i != slices) {
- glNormal3f(sinCache3a[i+1] * sintemp3,
- cosCache3a[i+1] * sintemp3,
- costemp3);
- }
- break;
- case GLU_NONE:
- default:
- break;
- }
- glVertex3f(sintemp2 * sinCache1a[i],
- sintemp2 * cosCache1a[i], zHigh);
- }
- } else {
- for (i = 0; i <= slices; i++) {
- switch(qobj->normals) {
- case GLU_SMOOTH:
- glNormal3f(sinCache2a[i] * sintemp3,
- cosCache2a[i] * sintemp3,
- costemp3);
- break;
- case GLU_FLAT:
- glNormal3f(sinCache3a[i] * sintemp3,
- cosCache3a[i] * sintemp3,
- costemp3);
- break;
- case GLU_NONE:
- default:
- break;
- }
- glVertex3f(sintemp2 * sinCache1a[i],
- sintemp2 * cosCache1a[i], zHigh);
- }
- }
- glEnd();
-
- /* High end next (j == stacks-1 iteration) */
- sintemp2 = sinCache1b[stacks-1];
- zHigh = cosCache1b[stacks-1];
- switch(qobj->normals) {
- case GLU_FLAT:
- sintemp3 = sinCache3b[stacks];
- costemp3 = cosCache3b[stacks];
- break;
- case GLU_SMOOTH:
- sintemp3 = sinCache2b[stacks-1];
- costemp3 = cosCache2b[stacks-1];
- glNormal3f(sinCache2a[stacks] * sinCache2b[stacks],
- cosCache2a[stacks] * sinCache2b[stacks],
- cosCache2b[stacks]);
- break;
- default:
- break;
- }
- glBegin(GL_TRIANGLE_FAN);
- glVertex3f(0.0, 0.0, -radius);
- if (qobj->orientation == GLU_OUTSIDE) {
- for (i = 0; i <= slices; i++) {
- switch(qobj->normals) {
- case GLU_SMOOTH:
- glNormal3f(sinCache2a[i] * sintemp3,
- cosCache2a[i] * sintemp3,
- costemp3);
- break;
- case GLU_FLAT:
- glNormal3f(sinCache3a[i] * sintemp3,
- cosCache3a[i] * sintemp3,
- costemp3);
- break;
- case GLU_NONE:
- default:
- break;
- }
- glVertex3f(sintemp2 * sinCache1a[i],
- sintemp2 * cosCache1a[i], zHigh);
- }
- } else {
- for (i = slices; i >= 0; i--) {
- switch(qobj->normals) {
- case GLU_SMOOTH:
- glNormal3f(sinCache2a[i] * sintemp3,
- cosCache2a[i] * sintemp3,
- costemp3);
- break;
- case GLU_FLAT:
- if (i != slices) {
- glNormal3f(sinCache3a[i+1] * sintemp3,
- cosCache3a[i+1] * sintemp3,
- costemp3);
- }
- break;
- case GLU_NONE:
- default:
- break;
- }
- glVertex3f(sintemp2 * sinCache1a[i],
- sintemp2 * cosCache1a[i], zHigh);
- }
- }
- glEnd();
- } else {
- start = 0;
- finish = stacks;
- }
- for (j = start; j < finish; j++) {
- zLow = cosCache1b[j];
- zHigh = cosCache1b[j+1];
- sintemp1 = sinCache1b[j];
- sintemp2 = sinCache1b[j+1];
- switch(qobj->normals) {
- case GLU_FLAT:
- sintemp4 = sinCache3b[j+1];
- costemp4 = cosCache3b[j+1];
- break;
- case GLU_SMOOTH:
- if (qobj->orientation == GLU_OUTSIDE) {
- sintemp3 = sinCache2b[j+1];
- costemp3 = cosCache2b[j+1];
- sintemp4 = sinCache2b[j];
- costemp4 = cosCache2b[j];
- } else {
- sintemp3 = sinCache2b[j];
- costemp3 = cosCache2b[j];
- sintemp4 = sinCache2b[j+1];
- costemp4 = cosCache2b[j+1];
- }
- break;
- default:
- break;
- }
-
- glBegin(GL_QUAD_STRIP);
- for (i = 0; i <= slices; i++) {
- switch(qobj->normals) {
- case GLU_SMOOTH:
- glNormal3f(sinCache2a[i] * sintemp3,
- cosCache2a[i] * sintemp3,
- costemp3);
- break;
- case GLU_FLAT:
- case GLU_NONE:
- default:
- break;
- }
- if (qobj->orientation == GLU_OUTSIDE) {
- if (qobj->textureCoords) {
- glTexCoord2f(1 - (float) i / slices,
- 1 - (float) (j+1) / stacks);
- }
- glVertex3f(sintemp2 * sinCache1a[i],
- sintemp2 * cosCache1a[i], zHigh);
- } else {
- if (qobj->textureCoords) {
- glTexCoord2f(1 - (float) i / slices,
- 1 - (float) j / stacks);
- }
- glVertex3f(sintemp1 * sinCache1a[i],
- sintemp1 * cosCache1a[i], zLow);
- }
- switch(qobj->normals) {
- case GLU_SMOOTH:
- glNormal3f(sinCache2a[i] * sintemp4,
- cosCache2a[i] * sintemp4,
- costemp4);
- break;
- case GLU_FLAT:
- glNormal3f(sinCache3a[i] * sintemp4,
- cosCache3a[i] * sintemp4,
- costemp4);
- break;
- case GLU_NONE:
- default:
- break;
- }
- if (qobj->orientation == GLU_OUTSIDE) {
- if (qobj->textureCoords) {
- glTexCoord2f(1 - (float) i / slices,
- 1 - (float) j / stacks);
- }
- glVertex3f(sintemp1 * sinCache1a[i],
- sintemp1 * cosCache1a[i], zLow);
- } else {
- if (qobj->textureCoords) {
- glTexCoord2f(1 - (float) i / slices,
- 1 - (float) (j+1) / stacks);
- }
- glVertex3f(sintemp2 * sinCache1a[i],
- sintemp2 * cosCache1a[i], zHigh);
- }
- }
- glEnd();
- }
- break;
- case GLU_POINT:
- glBegin(GL_POINTS);
- for (j = 0; j <= stacks; j++) {
- sintemp1 = sinCache1b[j];
- costemp1 = cosCache1b[j];
- switch(qobj->normals) {
- case GLU_FLAT:
- case GLU_SMOOTH:
- sintemp2 = sinCache2b[j];
- costemp2 = cosCache2b[j];
- break;
- default:
- break;
- }
- for (i = 0; i < slices; i++) {
- switch(qobj->normals) {
- case GLU_FLAT:
- case GLU_SMOOTH:
- glNormal3f(sinCache2a[i] * sintemp2,
- cosCache2a[i] * sintemp2,
- costemp2);
- break;
- case GLU_NONE:
- default:
- break;
- }
-
- zLow = j * radius / stacks;
-
- if (qobj->textureCoords) {
- glTexCoord2f(1 - (float) i / slices,
- 1 - (float) j / stacks);
- }
- glVertex3f(sintemp1 * sinCache1a[i],
- sintemp1 * cosCache1a[i], costemp1);
- }
- }
- glEnd();
- break;
- case GLU_LINE:
- case GLU_SILHOUETTE:
- for (j = 1; j < stacks; j++) {
- sintemp1 = sinCache1b[j];
- costemp1 = cosCache1b[j];
- switch(qobj->normals) {
- case GLU_FLAT:
- case GLU_SMOOTH:
- sintemp2 = sinCache2b[j];
- costemp2 = cosCache2b[j];
- break;
- default:
- break;
- }
-
- glBegin(GL_LINE_STRIP);
- for (i = 0; i <= slices; i++) {
- switch(qobj->normals) {
- case GLU_FLAT:
- glNormal3f(sinCache3a[i] * sintemp2,
- cosCache3a[i] * sintemp2,
- costemp2);
- break;
- case GLU_SMOOTH:
- glNormal3f(sinCache2a[i] * sintemp2,
- cosCache2a[i] * sintemp2,
- costemp2);
- break;
- case GLU_NONE:
- default:
- break;
- }
- if (qobj->textureCoords) {
- glTexCoord2f(1 - (float) i / slices,
- 1 - (float) j / stacks);
- }
- glVertex3f(sintemp1 * sinCache1a[i],
- sintemp1 * cosCache1a[i], costemp1);
- }
- glEnd();
- }
- for (i = 0; i < slices; i++) {
- sintemp1 = sinCache1a[i];
- costemp1 = cosCache1a[i];
- switch(qobj->normals) {
- case GLU_FLAT:
- case GLU_SMOOTH:
- sintemp2 = sinCache2a[i];
- costemp2 = cosCache2a[i];
- break;
- default:
- break;
- }
-
- glBegin(GL_LINE_STRIP);
- for (j = 0; j <= stacks; j++) {
- switch(qobj->normals) {
- case GLU_FLAT:
- glNormal3f(sintemp2 * sinCache3b[j],
- costemp2 * sinCache3b[j],
- cosCache3b[j]);
- break;
- case GLU_SMOOTH:
- glNormal3f(sintemp2 * sinCache2b[j],
- costemp2 * sinCache2b[j],
- cosCache2b[j]);
- break;
- case GLU_NONE:
- default:
- break;
- }
-
- if (qobj->textureCoords) {
- glTexCoord2f(1 - (float) i / slices,
- 1 - (float) j / stacks);
- }
- glVertex3f(sintemp1 * sinCache1b[j],
- costemp1 * sinCache1b[j], cosCache1b[j]);
- }
- glEnd();
- }
- break;
- default:
- break;
- }
-}
+++ /dev/null
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#include "gluos.h"
-#include <GL/glu.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-static const GLubyte versionString[] = "1.3";
-static const GLubyte extensionString[] =
- "GLU_EXT_nurbs_tessellator "
- "GLU_EXT_object_space_tess "
- ;
-
-const GLubyte * GLAPIENTRY
-gluGetString(GLenum name)
-{
-
- if (name == GLU_VERSION) {
- return versionString;
- } else if (name == GLU_EXTENSIONS) {
- return extensionString;
- }
- return NULL;
-}
-
-/* extName is an extension name.
- * extString is a string of extensions separated by blank(s). There may or
- * may not be leading or trailing blank(s) in extString.
- * This works in cases of extensions being prefixes of another like
- * GL_EXT_texture and GL_EXT_texture3D.
- * Returns GL_TRUE if extName is found otherwise it returns GL_FALSE.
- */
-GLboolean GLAPIENTRY
-gluCheckExtension(const GLubyte *extName, const GLubyte *extString)
-{
- GLboolean flag = GL_FALSE;
- char *word;
- char *lookHere;
- char *deleteThis;
-
- if (extString == NULL) return GL_FALSE;
-
- deleteThis = lookHere = (char *)malloc(strlen((const char *)extString)+1);
- if (lookHere == NULL)
- return GL_FALSE;
- /* strtok() will modify string, so copy it somewhere */
- strcpy(lookHere,(const char *)extString);
-
- while ((word= strtok(lookHere," ")) != NULL) {
- if (strcmp(word,(const char *)extName) == 0) {
- flag = GL_TRUE;
- break;
- }
- lookHere = NULL; /* get next token */
- }
- free((void *)deleteThis);
- return flag;
-} /* gluCheckExtension() */
-
-
-
-/*** registry.c ***/
+++ /dev/null
-!
-! ### UNIVERSAL procedures and global definitions extracted from MESAGL.MAP
-!
-case_sensitive=YES
-symbol_vector = (gluErrorString = PROCEDURE)
-symbol_vector = (__gluNURBSErrorString = PROCEDURE)
-symbol_vector = (__gluTessErrorString = PROCEDURE)
-symbol_vector = (gluBuild3DMipmaps = PROCEDURE)
-symbol_vector = (gluBuild3DMipmapLevels = PROCEDURE)
-symbol_vector = (gluBuild2DMipmaps = PROCEDURE)
-symbol_vector = (gluBuild2DMipmapLevels = PROCEDURE)
-symbol_vector = (gluBuild1DMipmaps = PROCEDURE)
-symbol_vector = (gluBuild1DMipmapLevels = PROCEDURE)
-symbol_vector = (gluScaleImage = PROCEDURE)
-symbol_vector = (gluPickMatrix = PROCEDURE)
-symbol_vector = (gluUnProject4 = PROCEDURE)
-symbol_vector = (gluUnProject = PROCEDURE)
-symbol_vector = (gluProject = PROCEDURE)
-symbol_vector = (gluLookAt = PROCEDURE)
-symbol_vector = (gluPerspective = PROCEDURE)
-symbol_vector = (gluOrtho2D = PROCEDURE)
-symbol_vector = (gluNewQuadric = PROCEDURE)
-symbol_vector = (gluSphere = PROCEDURE)
-symbol_vector = (gluPartialDisk = PROCEDURE)
-symbol_vector = (gluDisk = PROCEDURE)
-symbol_vector = (gluCylinder = PROCEDURE)
-symbol_vector = (gluQuadricDrawStyle = PROCEDURE)
-symbol_vector = (gluQuadricOrientation = PROCEDURE)
-symbol_vector = (gluQuadricTexture = PROCEDURE)
-symbol_vector = (gluQuadricNormals = PROCEDURE)
-symbol_vector = (gluQuadricCallback = PROCEDURE)
-symbol_vector = (gluDeleteQuadric = PROCEDURE)
-symbol_vector = (gluGetString = PROCEDURE)
-symbol_vector = (gluCheckExtension = PROCEDURE)
-symbol_vector = (gluTessEndContour = PROCEDURE)
-symbol_vector = (gluTessBeginContour = PROCEDURE)
-symbol_vector = (gluTessBeginPolygon = PROCEDURE)
-symbol_vector = (gluTessEndPolygon = PROCEDURE)
-symbol_vector = (gluEndPolygon = PROCEDURE)
-symbol_vector = (gluNextContour = PROCEDURE)
-symbol_vector = (gluBeginPolygon = PROCEDURE)
-symbol_vector = (gluTessVertex = PROCEDURE)
-symbol_vector = (gluTessCallback = PROCEDURE)
-symbol_vector = (gluTessNormal = PROCEDURE)
-symbol_vector = (gluGetTessProperty = PROCEDURE)
-symbol_vector = (gluTessProperty = PROCEDURE)
-symbol_vector = (gluDeleteTess = PROCEDURE)
-symbol_vector = (gluNewTess = PROCEDURE)
-symbol_vector = (gluNurbsCallbackDataEXT = PROCEDURE)
-symbol_vector = (gluNurbsCallbackData = PROCEDURE)
-symbol_vector = (gluNurbsCallback = PROCEDURE)
-symbol_vector = (gluGetNurbsProperty = PROCEDURE)
-symbol_vector = (gluNurbsProperty = PROCEDURE)
-symbol_vector = (gluLoadSamplingMatrices = PROCEDURE)
-symbol_vector = (gluNurbsSurface = PROCEDURE)
-symbol_vector = (gluNurbsCurve = PROCEDURE)
-symbol_vector = (gluPwlCurve = PROCEDURE)
-symbol_vector = (gluEndTrim = PROCEDURE)
-symbol_vector = (gluBeginTrim = PROCEDURE)
-symbol_vector = (gluEndSurface = PROCEDURE)
-symbol_vector = (gluEndCurve = PROCEDURE)
-symbol_vector = (gluBeginCurve = PROCEDURE)
-symbol_vector = (gluBeginSurface = PROCEDURE)
-symbol_vector = (gluDeleteNurbsTessellatorEXT = PROCEDURE)
-symbol_vector = (gluDeleteNurbsRenderer = PROCEDURE)
-symbol_vector = (gluNewNurbsRenderer = PROCEDURE)
-symbol_vector = (glu_LOD_eval_list = PROCEDURE)