home *** CD-ROM | disk | FTP | other *** search
/ Aminet 10 / aminetcdnumber101996.iso / Aminet / gfx / x11 / Mesa_Amiwin.lha / Mesa-Amiwin / src-glu / nurbs.c < prev    next >
C/C++ Source or Header  |  1995-11-17  |  17KB  |  660 lines

  1. /* nurbs.c */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  1.2
  6.  * Copyright (C) 1995  Brian Paul  (brianp@ssec.wisc.edu)
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25. $Id: nurbs.c,v 1.14 1995/11/03 14:11:50 brianp Exp $
  26.  
  27. $Log: nurbs.c,v $
  28.  * Revision 1.14  1995/11/03  14:11:50  brianp
  29.  * Bogdan's November 3, 1995 updates
  30.  *
  31.  * Revision 1.13  1995/09/20  18:25:57  brianp
  32.  * removed Bogdan's old email address
  33.  *
  34.  * Revision 1.12  1995/07/31  16:29:49  brianp
  35.  * applied Bogdan's patch from July 31, 1995
  36.  *
  37.  * Revision 1.11  1995/07/28  21:36:36  brianp
  38.  * changed all GLUenum to GLenum
  39.  *
  40.  * Revision 1.10  1995/07/28  14:44:14  brianp
  41.  * incorporated Bogdan's July 27 revisions
  42.  *
  43.  * Revision 1.9  1995/05/30  13:12:39  brianp
  44.  * added gluNurbsCallback() stub
  45.  *
  46.  * Revision 1.8  1995/05/29  20:09:11  brianp
  47.  * added gluGetNurbsProperty()
  48.  *
  49.  * Revision 1.7  1995/05/24  13:44:11  brianp
  50.  * added gluBeginTrim, gluEndTrim, gluPwlCurve stubs
  51.  *
  52.  * Revision 1.6  1995/05/22  16:56:20  brianp
  53.  * Release 1.2
  54.  *
  55.  * Revision 1.5  1995/05/16  19:17:21  brianp
  56.  * minor changes to allow compilation with real OpenGL headers
  57.  *
  58.  * Revision 1.4  1995/04/28  20:06:23  brianp
  59.  * print an error message when trying to use gluNewNurbsRenderer()
  60.  *
  61.  * Revision 1.3  1995/04/28  14:37:32  brianp
  62.  * moved GLUnurbsObj struct from .h to .c file
  63.  *
  64.  * Revision 1.2  1995/03/04  19:39:18  brianp
  65.  * version 1.1 beta
  66.  *
  67.  * Revision 1.1  1995/02/24  15:45:01  brianp
  68.  * Initial revision
  69.  *
  70.  */
  71.  
  72.  
  73. /*
  74.  * NURBS implementation written by Bogdan Sikorski (bogdan@cira.it)
  75.  * See README-nurbs for more info.
  76.  */
  77.  
  78.  
  79. #include <math.h>
  80. #include <stdio.h>
  81. #include <stdlib.h>
  82. #include "nurbs.h"
  83.  
  84.  
  85. void
  86. call_user_error( GLUnurbsObj *nobj, GLenum error )
  87. {
  88.     nobj->error=error;
  89.     if(nobj->error_callback != NULL) {
  90.         (*(nobj->error_callback))(error);
  91.     }
  92.     else {
  93.        printf("NURBS error %d %s\n", error, gluErrorString(error) );
  94.     }
  95. }
  96.  
  97.  
  98.  
  99. GLUnurbsObj *gluNewNurbsRenderer( void )
  100. {
  101.    GLUnurbsObj *n;
  102.    GLfloat tmp_viewport[4];
  103.    GLint i,j;
  104.  
  105.    n = (GLUnurbsObj *) malloc( sizeof(GLUnurbsObj) );
  106.    if (n) {
  107.       /* init */
  108.       n->culling=GL_FALSE;
  109.       n->nurbs_type=GLU_NURBS_NONE;
  110.       n->error=GLU_NO_ERROR;
  111.       n->error_callback=NULL;
  112.       n->auto_load_matrix=GL_TRUE;
  113.       n->sampling_tolerance=50.0;
  114.       n->display_mode=GLU_FILL;
  115.       /* in case the user doesn't supply the sampling matrices */
  116.       /* set projection and modelview to identity */
  117.       for(i=0;i<4;i++)
  118.           for(j=0;j<4;j++)
  119.               if(i==j)
  120.               {
  121.                 n->sampling_matrices.model[i*4+j]=1.0;
  122.                 n->sampling_matrices.proj[i*4+j]=1.0;
  123.             }
  124.             else
  125.               {
  126.                 n->sampling_matrices.model[i*4+j]=0.0;
  127.                 n->sampling_matrices.proj[i*4+j]=0.0;
  128.             }
  129.       /* and set the viewport sampling matrix to current ciewport */
  130.       glGetFloatv(GL_VIEWPORT,tmp_viewport);
  131.       for(i=0;i<4;i++)
  132.           n->sampling_matrices.viewport[i]=tmp_viewport[i];
  133.       n->trim=NULL;
  134.    }
  135.    return n;
  136. }
  137.  
  138.  
  139.  
  140. void gluDeleteNurbsRenderer( GLUnurbsObj *nobj )
  141. {
  142.    if (nobj) {
  143.       free( nobj );
  144.    }
  145. }
  146.  
  147.  
  148.  
  149. void gluLoadSamplingMatrices( GLUnurbsObj *nobj,
  150.                   const GLfloat modelMatrix[16],
  151.                   const GLfloat projMatrix[16],
  152.                   const GLint viewport[4] )
  153. {
  154.     GLint    i;
  155.  
  156.     for(i=0;i<16;i++)
  157.     {
  158.         nobj->sampling_matrices.model[i]=modelMatrix[i];
  159.         nobj->sampling_matrices.proj[i]=projMatrix[i];
  160.     }
  161.     for(i=0;i<4;i++)
  162.         nobj->sampling_matrices.viewport[i]=viewport[i];
  163. }
  164.  
  165.  
  166. void gluNurbsProperty( GLUnurbsObj *nobj, GLenum property, GLfloat value )
  167. {
  168.    GLenum val;
  169.  
  170.    switch (property) {
  171.       case GLU_SAMPLING_TOLERANCE:
  172.            if(value <= 0.0)
  173.            {
  174.                call_user_error(nobj,GLU_INVALID_VALUE);
  175.                return;
  176.          }
  177.          nobj->sampling_tolerance=value;
  178.          break;
  179.       case GLU_DISPLAY_MODE:
  180.          val=(GLenum)value;
  181.          if(val!=GLU_FILL && val!=GLU_OUTLINE_POLYGON && val!=GLU_OUTLINE_PATCH)
  182.          {
  183.              call_user_error(nobj,GLU_INVALID_ENUM);
  184.              return;
  185.          }
  186.          if(nobj->nurbs_type==GLU_NURBS_CURVE)
  187.          {
  188.              call_user_error(nobj,GLU_NURBS_ERROR26);
  189.              return;
  190.          }
  191.          nobj->display_mode=val;
  192. if(val==GLU_OUTLINE_PATCH)
  193.     fprintf(stderr,"NURBS, for the moment, can display only in POLYGON mode\n");
  194.          break;
  195.       case GLU_CULLING:
  196.          val=(GLenum)value;
  197.          if(val!=GL_TRUE && val!=GL_FALSE)
  198.          {
  199.              call_user_error(nobj,GLU_INVALID_ENUM);
  200.              return;
  201.          }
  202.          nobj->culling = (GLboolean) value;
  203.          break;
  204.       case GLU_AUTO_LOAD_MATRIX:
  205.          val=(GLenum)value;
  206.          if(val!=GL_TRUE && val!=GL_FALSE)
  207.          {
  208.              call_user_error(nobj,GLU_INVALID_ENUM);
  209.              return;
  210.          }
  211.          nobj->auto_load_matrix = (GLboolean) value;
  212.          break;
  213.       default:
  214.          call_user_error(nobj,GLU_NURBS_ERROR26);
  215.    }
  216. }
  217.  
  218.  
  219. void gluGetNurbsProperty( GLUnurbsObj *nobj, GLenum property, GLfloat *value )
  220. {
  221.    switch (property) {
  222.       case GLU_SAMPLING_TOLERANCE:
  223.          *value = nobj->sampling_tolerance;
  224.          break;
  225.       case GLU_DISPLAY_MODE:
  226.          *value = (GLfloat) nobj->display_mode;
  227.          break;
  228.       case GLU_CULLING:
  229.      *value = nobj->culling ? 1.0 : 0.0;
  230.          break;
  231.       case GLU_AUTO_LOAD_MATRIX:
  232.          *value = nobj->auto_load_matrix ? 1.0 : 0.0;
  233.      break;
  234.       default:
  235.          call_user_error(nobj,GLU_INVALID_ENUM);
  236.    }
  237. }
  238.  
  239.  
  240.  
  241. void gluBeginCurve( GLUnurbsObj *nobj )
  242. {
  243.     if(nobj->nurbs_type==GLU_NURBS_CURVE)
  244.     {
  245.         call_user_error(nobj,GLU_NURBS_ERROR6);
  246.         return;
  247.     }
  248.     nobj->nurbs_type=GLU_NURBS_CURVE;
  249.     nobj->curve.geom.type=GLU_INVALID_ENUM;
  250.     nobj->curve.color.type=GLU_INVALID_ENUM;
  251.     nobj->curve.texture.type=GLU_INVALID_ENUM;
  252.     nobj->curve.normal.type=GLU_INVALID_ENUM;
  253. }
  254.  
  255.  
  256. void gluEndCurve( GLUnurbsObj * nobj )
  257. {
  258.     if(nobj->nurbs_type==GLU_NURBS_NONE)
  259.     {
  260.         call_user_error(nobj,GLU_NURBS_ERROR7);
  261.         return;
  262.     }
  263.     if(nobj->curve.geom.type==GLU_INVALID_ENUM)
  264.     {
  265.         call_user_error(nobj,GLU_NURBS_ERROR8);
  266.         nobj->nurbs_type=GLU_NURBS_NONE;
  267.         return;
  268.     }
  269.     glPushAttrib(GL_EVAL_BIT | GL_ENABLE_BIT);
  270.     glDisable(GL_MAP1_VERTEX_3);
  271.     glDisable(GL_MAP1_VERTEX_4);
  272.     glDisable(GL_MAP1_INDEX);
  273.     glDisable(GL_MAP1_COLOR_4);
  274.     glDisable(GL_MAP1_NORMAL);
  275.     glDisable(GL_MAP1_TEXTURE_COORD_1);
  276.     glDisable(GL_MAP1_TEXTURE_COORD_2);
  277.     glDisable(GL_MAP1_TEXTURE_COORD_3);
  278.     glDisable(GL_MAP1_TEXTURE_COORD_4);
  279.     glDisable(GL_MAP2_VERTEX_3);
  280.     glDisable(GL_MAP2_VERTEX_4);
  281.     glDisable(GL_MAP2_INDEX);
  282.     glDisable(GL_MAP2_COLOR_4);
  283.     glDisable(GL_MAP2_NORMAL);
  284.     glDisable(GL_MAP2_TEXTURE_COORD_1);
  285.     glDisable(GL_MAP2_TEXTURE_COORD_2);
  286.     glDisable(GL_MAP2_TEXTURE_COORD_3);
  287.     glDisable(GL_MAP2_TEXTURE_COORD_4);
  288.     do_nurbs_curve(nobj);
  289.     glPopAttrib();
  290.     nobj->nurbs_type=GLU_NURBS_NONE;
  291. }
  292.  
  293.  
  294. void gluNurbsCurve( GLUnurbsObj *nobj, GLint nknots, GLfloat *knot,
  295.             GLint stride, GLfloat *ctlarray, GLint order, GLenum type )
  296. {
  297.     if(nobj->nurbs_type==GLU_NURBS_TRIM)
  298.     {
  299.         nurbs_trim *ptr1;
  300.         trim_list *ptr2;
  301.  
  302. return;
  303.         if(type!=GLU_MAP1_TRIM_2 && type!=GLU_MAP1_TRIM_3)
  304.         {
  305.             call_user_error(nobj,GLU_NURBS_ERROR14);
  306.             return;
  307.         }
  308.         for(ptr1=nobj->trim;ptr1->next;ptr1=ptr1->next);
  309.         if(ptr1->trim_loop)
  310.         {
  311.             for(ptr2=ptr1->trim_loop;ptr2->next;ptr2=ptr2->next);
  312.             if((ptr2->next=(trim_list *)malloc(sizeof(trim_list)))==NULL)
  313.             {
  314.                 call_user_error(nobj,GLU_OUT_OF_MEMORY);
  315.                 return;
  316.             }
  317.             ptr2=ptr2->next;
  318.         }
  319.         else
  320.         {
  321.             if((ptr2=(trim_list *)malloc(sizeof(trim_list)))==NULL)
  322.             {
  323.                 call_user_error(nobj,GLU_OUT_OF_MEMORY);
  324.                 return;
  325.             }
  326.             ptr1->trim_loop=ptr2;
  327.         }
  328.         ptr2->trim_type=GLU_TRIM_NURBS;
  329.         ptr2->curve.nurbs_curve.knot_count=nknots;
  330.         ptr2->curve.nurbs_curve.knot=knot;
  331.         ptr2->curve.nurbs_curve.stride=stride;
  332.         ptr2->curve.nurbs_curve.ctrlarray=ctlarray;
  333.         ptr2->curve.nurbs_curve.order=order;
  334.         ptr2->curve.nurbs_curve.dim= (type==GLU_MAP1_TRIM_2 ? 2 : 3 );
  335.         ptr2->curve.nurbs_curve.type=type;
  336.         ptr2->next=NULL;
  337.     }
  338.     else
  339.     {
  340.         if(type==GLU_MAP1_TRIM_2 || type==GLU_MAP1_TRIM_3)
  341.         {
  342.             call_user_error(nobj,GLU_NURBS_ERROR22);
  343.             return;
  344.         }
  345.         if(nobj->nurbs_type!=GLU_NURBS_CURVE)
  346.         {
  347.             call_user_error(nobj,GLU_NURBS_ERROR10);
  348.             return;
  349.         }
  350.         switch(type)
  351.         {
  352.             case GL_MAP1_VERTEX_3:
  353.             case GL_MAP1_VERTEX_4:
  354.                 if(nobj->curve.geom.type!=GLU_INVALID_ENUM)
  355.                 {
  356.                     call_user_error(nobj,GLU_NURBS_ERROR8);
  357.                     return;
  358.                 }
  359.                 nobj->curve.geom.type=type;
  360.                 nobj->curve.geom.knot_count=nknots;
  361.                 nobj->curve.geom.knot=knot;
  362.                 nobj->curve.geom.stride=stride;
  363.                 nobj->curve.geom.ctrlarray=ctlarray;
  364.                 nobj->curve.geom.order=order;
  365.                 break;
  366.             case GL_MAP1_INDEX:
  367.             case GL_MAP1_COLOR_4:
  368.                 nobj->curve.color.type=type;
  369.                 nobj->curve.color.knot_count=nknots;
  370.                 nobj->curve.color.knot=knot;
  371.                 nobj->curve.color.stride=stride;
  372.                 nobj->curve.color.ctrlarray=ctlarray;
  373.                 nobj->curve.color.order=order;
  374.                 break;
  375.             case GL_MAP1_NORMAL:
  376.                 nobj->curve.normal.type=type;
  377.                 nobj->curve.normal.knot_count=nknots;
  378.                 nobj->curve.normal.knot=knot;
  379.                 nobj->curve.normal.stride=stride;
  380.                 nobj->curve.normal.ctrlarray=ctlarray;
  381.                 nobj->curve.normal.order=order;
  382.                 break;
  383.             case GL_MAP1_TEXTURE_COORD_1:
  384.             case GL_MAP1_TEXTURE_COORD_2:
  385.             case GL_MAP1_TEXTURE_COORD_3:
  386.             case GL_MAP1_TEXTURE_COORD_4:
  387.                 nobj->curve.texture.type=type;
  388.                 nobj->curve.texture.knot_count=nknots;
  389.                 nobj->curve.texture.knot=knot;
  390.                 nobj->curve.texture.stride=stride;
  391.                 nobj->curve.texture.ctrlarray=ctlarray;
  392.                 nobj->curve.texture.order=order;
  393.                 break;
  394.             default:
  395.                  call_user_error(nobj,GLU_INVALID_ENUM);
  396.         }
  397.     }
  398. }
  399.  
  400.  
  401. void gluBeginSurface( GLUnurbsObj *nobj )
  402. {
  403.     switch(nobj->nurbs_type)
  404.     {
  405.         case GLU_NURBS_NONE:
  406.             nobj->nurbs_type=GLU_NURBS_SURFACE;
  407.             nobj->surface.geom.type=GLU_INVALID_ENUM;
  408.             nobj->surface.color.type=GLU_INVALID_ENUM;
  409.             nobj->surface.texture.type=GLU_INVALID_ENUM;
  410.             nobj->surface.normal.type=GLU_INVALID_ENUM;
  411.             break;
  412.         case GLU_NURBS_TRIM:
  413.             call_user_error(nobj,GLU_NURBS_ERROR16);
  414.             break;
  415.         case GLU_NURBS_SURFACE:
  416.         case GLU_NURBS_NO_TRIM:
  417.         case GLU_NURBS_TRIM_DONE:
  418.             call_user_error(nobj,GLU_NURBS_ERROR27);
  419.             break;
  420.         case GLU_NURBS_CURVE:
  421.             call_user_error(nobj,GLU_NURBS_ERROR6);
  422.             break;
  423.     }
  424. }
  425.  
  426.  
  427. void gluEndSurface( GLUnurbsObj * nobj )
  428. {
  429.     switch(nobj->nurbs_type)
  430.     {
  431.         case GLU_NURBS_NONE:
  432.             call_user_error(nobj,GLU_NURBS_ERROR13);
  433.             break;
  434.         case GLU_NURBS_TRIM:
  435.             call_user_error(nobj,GLU_NURBS_ERROR12);
  436.             break;
  437.         case GLU_NURBS_TRIM_DONE:
  438. /*            if(nobj->trim->trim_loop==NULL)
  439.             {
  440.                 call_user_error(nobj,GLU_NURBS_ERROR18);
  441.                 return;
  442.             }*/
  443.             /* no break - fallthrough */
  444.         case GLU_NURBS_NO_TRIM:
  445.             glPushAttrib(GL_EVAL_BIT | GL_ENABLE_BIT);
  446.             glDisable(GL_MAP2_VERTEX_3);
  447.             glDisable(GL_MAP2_VERTEX_4);
  448.             glDisable(GL_MAP2_INDEX);
  449.             glDisable(GL_MAP2_COLOR_4);
  450.             glDisable(GL_MAP2_NORMAL);
  451.             glDisable(GL_MAP2_TEXTURE_COORD_1);
  452.             glDisable(GL_MAP2_TEXTURE_COORD_2);
  453.             glDisable(GL_MAP2_TEXTURE_COORD_3);
  454.             glDisable(GL_MAP2_TEXTURE_COORD_4);
  455. /*            glDisable(GL_MAP1_VERTEX_3);
  456.             glDisable(GL_MAP1_VERTEX_4);
  457.             glDisable(GL_MAP1_INDEX);
  458.             glDisable(GL_MAP1_COLOR_4);
  459.             glDisable(GL_MAP1_NORMAL);
  460.             glDisable(GL_MAP1_TEXTURE_COORD_1);
  461.             glDisable(GL_MAP1_TEXTURE_COORD_2);
  462.             glDisable(GL_MAP1_TEXTURE_COORD_3);
  463.             glDisable(GL_MAP1_TEXTURE_COORD_4);*/
  464.             do_nurbs_surface(nobj);
  465.             glPopAttrib();
  466.             break;
  467.         default:
  468.             call_user_error(nobj,GLU_NURBS_ERROR8);
  469.     }
  470.     nobj->nurbs_type=GLU_NURBS_NONE;
  471. }
  472.  
  473.  
  474. void gluNurbsSurface( GLUnurbsObj *nobj,
  475.               GLint sknot_count, GLfloat *sknot,
  476.               GLint tknot_count, GLfloat *tknot,
  477.               GLint s_stride, GLint t_stride,
  478.               GLfloat *ctrlarray,
  479.               GLint sorder, GLint torder,
  480.               GLenum type )
  481. {
  482.     if(nobj->nurbs_type==GLU_NURBS_NO_TRIM || nobj->nurbs_type==GLU_NURBS_TRIM ||
  483.         nobj->nurbs_type==GLU_NURBS_TRIM_DONE)
  484.     {
  485.         if(type==GL_MAP2_VERTEX_3 || type==GL_MAP2_VERTEX_4)
  486.         {
  487.             call_user_error(nobj,GLU_NURBS_ERROR8);
  488.             return;
  489.         }
  490.     }
  491.     else
  492.     if(nobj->nurbs_type!=GLU_NURBS_SURFACE)
  493.     {
  494.         call_user_error(nobj,GLU_NURBS_ERROR11);
  495.         return;
  496.     }
  497.     switch(type)
  498.     {
  499.         case GL_MAP2_VERTEX_3:
  500.         case GL_MAP2_VERTEX_4:
  501.             nobj->surface.geom.sknot_count=sknot_count;
  502.             nobj->surface.geom.sknot=sknot;
  503.             nobj->surface.geom.tknot_count=tknot_count;
  504.             nobj->surface.geom.tknot=tknot;
  505.             nobj->surface.geom.s_stride=s_stride;
  506.             nobj->surface.geom.t_stride=t_stride;
  507.             nobj->surface.geom.ctrlarray=ctrlarray;
  508.             nobj->surface.geom.sorder=sorder;
  509.             nobj->surface.geom.torder=torder;
  510.             nobj->surface.geom.type=type;
  511.             nobj->nurbs_type=GLU_NURBS_NO_TRIM;
  512.             break;
  513.         case GL_MAP2_INDEX:
  514.         case GL_MAP2_COLOR_4:
  515.             nobj->surface.color.sknot_count=sknot_count;
  516.             nobj->surface.color.sknot=sknot;
  517.             nobj->surface.color.tknot_count=tknot_count;
  518.             nobj->surface.color.tknot=tknot;
  519.             nobj->surface.color.s_stride=s_stride;
  520.             nobj->surface.color.t_stride=t_stride;
  521.             nobj->surface.color.ctrlarray=ctrlarray;
  522.             nobj->surface.color.sorder=sorder;
  523.             nobj->surface.color.torder=torder;
  524.             nobj->surface.color.type=type;
  525.             break;
  526.         case GL_MAP2_NORMAL:
  527.             nobj->surface.normal.sknot_count=sknot_count;
  528.             nobj->surface.normal.sknot=sknot;
  529.             nobj->surface.normal.tknot_count=tknot_count;
  530.             nobj->surface.normal.tknot=tknot;
  531.             nobj->surface.normal.s_stride=s_stride;
  532.             nobj->surface.normal.t_stride=t_stride;
  533.             nobj->surface.normal.ctrlarray=ctrlarray;
  534.             nobj->surface.normal.sorder=sorder;
  535.             nobj->surface.normal.torder=torder;
  536.             nobj->surface.normal.type=type;
  537.             break;
  538.         case GL_MAP2_TEXTURE_COORD_1:
  539.         case GL_MAP2_TEXTURE_COORD_2:
  540.         case GL_MAP2_TEXTURE_COORD_3:
  541.         case GL_MAP2_TEXTURE_COORD_4:
  542.             nobj->surface.texture.sknot_count=sknot_count;
  543.             nobj->surface.texture.sknot=sknot;
  544.             nobj->surface.texture.tknot_count=tknot_count;
  545.             nobj->surface.texture.tknot=tknot;
  546.             nobj->surface.texture.s_stride=s_stride;
  547.             nobj->surface.texture.t_stride=t_stride;
  548.             nobj->surface.texture.ctrlarray=ctrlarray;
  549.             nobj->surface.texture.sorder=sorder;
  550.             nobj->surface.texture.torder=torder;
  551.             nobj->surface.texture.type=type;
  552.             break;
  553.         default:
  554.              call_user_error(nobj,GLU_INVALID_ENUM);
  555.     }
  556. }
  557.  
  558.  
  559. void
  560. gluNurbsCallback( GLUnurbsObj *nobj, GLenum which, void (*fn)())
  561. {
  562.     nobj->error_callback=fn;
  563.     if(which!=GLU_ERROR)
  564.         call_user_error(nobj,GLU_INVALID_ENUM);
  565. }
  566.  
  567. void
  568. gluBeginTrim( GLUnurbsObj *nobj )
  569. {
  570.     nurbs_trim *ptr;
  571.  
  572.     if(nobj->nurbs_type!=GLU_NURBS_TRIM_DONE)
  573.         if(nobj->nurbs_type!=GLU_NURBS_NO_TRIM)
  574.         {
  575.             call_user_error(nobj,GLU_NURBS_ERROR15);
  576.             return;
  577.         }
  578.     nobj->nurbs_type=GLU_NURBS_TRIM;
  579. fprintf(stderr,"NURBS - trimming not supported yet\n");
  580. /*    if((ptr=(nurbs_trim *)malloc(sizeof(nurbs_trim)))==NULL)
  581.     {
  582.         call_user_error(nobj,GLU_OUT_OF_MEMORY);
  583.         return;
  584.     }
  585.     if(nobj->trim)
  586.     {
  587.         nurbs_trim *tmp_ptr;
  588.  
  589.         for(tmp_ptr=nobj->trim;tmp_ptr->next;tmp_ptr=tmp_ptr->next);
  590.         tmp_ptr->next=ptr;
  591.     }
  592.     else
  593.         nobj->trim=ptr;
  594.     ptr->trim_loop=NULL;
  595.     ptr->segments=NULL;
  596.     ptr->next=NULL;*/
  597. }
  598.  
  599. void
  600. gluPwlCurve( GLUnurbsObj *nobj, GLint count, GLfloat *array, GLint stride,
  601.     GLenum type)
  602. {
  603.     nurbs_trim *ptr1;
  604.     trim_list *ptr2;
  605.  
  606.     if(nobj->nurbs_type==GLU_NURBS_CURVE)
  607.     {
  608.         call_user_error(nobj,GLU_NURBS_ERROR9);
  609.         return;
  610.     }
  611.     if(nobj->nurbs_type==GLU_NURBS_NONE)
  612.     {
  613.         call_user_error(nobj,GLU_NURBS_ERROR19);
  614.         return;
  615.     }
  616.     if(type!=GLU_MAP1_TRIM_2 && type!=GLU_MAP1_TRIM_3)
  617.     {
  618.         call_user_error(nobj,GLU_NURBS_ERROR14);
  619.         return;
  620.     }
  621. /*    for(ptr1=nobj->trim;ptr1->next;ptr1=ptr1->next);
  622.     if(ptr1->trim_loop)
  623.     {
  624.         for(ptr2=ptr1->trim_loop;ptr2->next;ptr2=ptr2->next);
  625.         if((ptr2->next=(trim_list *)malloc(sizeof(trim_list)))==NULL)
  626.         {
  627.             call_user_error(nobj,GLU_OUT_OF_MEMORY);
  628.             return;
  629.         }
  630.         ptr2=ptr2->next;
  631.     }
  632.     else
  633.     {
  634.         if((ptr2=(trim_list *)malloc(sizeof(trim_list)))==NULL)
  635.         {
  636.             call_user_error(nobj,GLU_OUT_OF_MEMORY);
  637.             return;
  638.         }
  639.         ptr1->trim_loop=ptr2;
  640.     }
  641.     ptr2->trim_type=GLU_TRIM_PWL;
  642.     ptr2->curve.pwl_curve.pt_count=count;
  643.     ptr2->curve.pwl_curve.ctrlarray=array;
  644.     ptr2->curve.pwl_curve.stride=stride;
  645.     ptr2->curve.pwl_curve.dim= (type==GLU_MAP1_TRIM_2 ? 2 : 3 );
  646.     ptr2->curve.pwl_curve.type=type;
  647.     ptr2->next=NULL;*/
  648. }
  649.  
  650. void
  651. gluEndTrim( GLUnurbsObj *nobj )
  652. {
  653.     if(nobj->nurbs_type!=GLU_NURBS_TRIM)
  654.     {
  655.         call_user_error(nobj,GLU_NURBS_ERROR17);
  656.         return;
  657.     }
  658.     nobj->nurbs_type=GLU_NURBS_TRIM_DONE;
  659. }
  660.