bezierPatch.cc revision f220fa62
1/*
2** License Applicability. Except to the extent portions of this file are
3** made subject to an alternative license as permitted in the SGI Free
4** Software License B, Version 1.1 (the "License"), the contents of this
5** file are subject only to the provisions of the License. You may not use
6** this file except in compliance with the License. You may obtain a copy
7** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
8** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
9**
10** http://oss.sgi.com/projects/FreeB
11**
12** Note that, as provided in the License, the Software is distributed on an
13** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
14** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
15** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
16** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
17**
18** Original Code. The Original Code is: OpenGL Sample Implementation,
19** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
20** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
21** Copyright in any portions created by third parties is as indicated
22** elsewhere herein. All Rights Reserved.
23**
24** Additional Notice Provisions: The application programming interfaces
25** established by SGI in conjunction with the Original Code are The
26** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
27** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
28** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
29** Window System(R) (Version 1.3), released October 19, 1998. This software
30** was created using the OpenGL(R) version 1.2.1 Sample Implementation
31** published by SGI, but has not been independently verified as being
32** compliant with the OpenGL(R) version 1.2.1 Specification.
33**
34*/
35/*
36*/
37
38#include "gluos.h"
39#include <stdlib.h>
40#include <stdio.h>
41#include <assert.h>
42#include <GL/glu.h> /*for drawing bzier patch*/
43#include "bezierPatch.h"
44#include "bezierEval.h"
45
46/*
47 *allocate an instance of bezierPatch. The control points are unknown. But
48 *the space of this array is allocated with size of
49 *   uorder*vorder*dimension
50 *
51 */
52bezierPatch* bezierPatchMake(float umin, float vmin, float umax, float vmax, int uorder, int vorder, int dimension)
53{
54  bezierPatch* ret = (bezierPatch*) malloc(sizeof(bezierPatch));
55  assert(ret);
56  ret->umin = umin;
57  ret->vmin = vmin;
58  ret->umax = umax;
59  ret->vmax = vmax;
60  ret->uorder = uorder;
61  ret->vorder = vorder;
62  ret->dimension = dimension;
63  ret->ctlpoints = (float*) malloc(sizeof(float) * dimension * uorder * vorder);
64  assert(ret->ctlpoints);
65
66  ret->next = NULL;
67
68  return ret;
69}
70
71bezierPatch* bezierPatchMake2(float umin, float vmin, float umax, float vmax, int uorder, int vorder, int dimension, int ustride, int vstride,  float* ctlpoints)
72{
73  bezierPatch* ret = (bezierPatch*) malloc(sizeof(bezierPatch));
74  assert(ret);
75  ret->umin = umin;
76  ret->vmin = vmin;
77  ret->umax = umax;
78  ret->vmax = vmax;
79  ret->uorder = uorder;
80  ret->vorder = vorder;
81  ret->dimension = dimension;
82  ret->ctlpoints = (float*) malloc(sizeof(float) * dimension * uorder * vorder);
83  assert(ret->ctlpoints);
84
85  /*copy the control points there*/
86  int the_ustride = vorder * dimension;
87  int the_vstride = dimension;
88  for(int i=0; i<uorder; i++)
89    for(int j=0; j<vorder; j++)
90      for(int k=0; k<dimension; k++)
91	ret->ctlpoints[i * the_ustride + j*the_vstride+k] = ctlpoints[i*ustride+j*vstride+k];
92
93  ret->next = NULL;
94
95  return ret;
96}
97
98/*
99 *deallocate the space as allocated by Make
100 */
101void bezierPatchDelete(bezierPatch *b)
102{
103  free(b->ctlpoints);
104  free(b);
105}
106
107/*delete the whole linked list
108 */
109void bezierPatchDeleteList(bezierPatch *b)
110{
111  bezierPatch *temp;
112  while (b != NULL) {
113    temp = b;
114    b = b->next;
115    bezierPatchDelete(temp);
116  }
117}
118
119bezierPatch* bezierPatchInsert(bezierPatch *list, bezierPatch *b)
120{
121  b->next = list;
122  return b;
123}
124
125/*print the data stored in this patch*/
126void bezierPatchPrint(bezierPatch *b)
127{
128  printf("bezierPatch:\n");
129  printf("umin,umax=(%f,%f), (vmin, vmax)=(%f,%f)\n", b->umin, b->umax, b->vmin, b->vmax);
130  printf("uorder=%i, vorder=%i\n", b->uorder, b->vorder);
131  printf("idmension = %i\n", b->dimension);
132}
133
134/*print the whole list*/
135void bezierPatchPrintList(bezierPatch *list)
136{
137  bezierPatch* temp;
138  for(temp=list; temp != NULL; temp = temp->next)
139    bezierPatchPrint(temp);
140}
141
142void bezierPatchEval(bezierPatch *b, float u, float v, float ret[])
143{
144  if(   u >= b->umin && u<= b->umax
145     && v >= b->vmin && v<= b->vmax)
146    {
147
148      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);
149
150     }
151  else if(b->next != NULL)
152    bezierPatchEval(b->next, u,v, ret);
153  else
154    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);
155}
156
157/*the returned normal is normlized
158 */
159void bezierPatchEvalNormal(bezierPatch *b, float u, float v, float ret[])
160{
161  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);
162
163  if(   u >= b->umin && u<= b->umax
164     && v >= b->vmin && v<= b->vmax)
165    {
166      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);
167     }
168  else if(b->next != NULL)
169    bezierPatchEvalNormal(b->next, u,v, ret);
170  else
171    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);
172
173}
174
175void bezierPatchDraw(bezierPatch *bpatch, int u_reso, int v_reso)
176{
177  if(bpatch->dimension == 3)
178    glMap2f(GL_MAP2_VERTEX_3, bpatch->umin, bpatch->umax, 3*bpatch->vorder, bpatch->uorder, bpatch->vmin, bpatch->vmax,3, bpatch->vorder, (GLfloat*) bpatch->ctlpoints);
179  else
180    glMap2f(GL_MAP2_VERTEX_4, bpatch->umin, bpatch->umax, 4*bpatch->vorder, bpatch->uorder, bpatch->vmin, bpatch->vmax,3, bpatch->vorder, (GLfloat*) bpatch->ctlpoints);
181
182  glMapGrid2f(u_reso, bpatch->umin, bpatch->umax,
183	      v_reso, bpatch->vmin, bpatch->vmax);
184  glEvalMesh2(GL_LINE, 0, u_reso, 0, v_reso);
185}
186
187void bezierPatchListDraw(bezierPatch *list, int u_reso, int v_reso)
188{
189  bezierPatch *temp;
190glEnable(GL_LIGHTING);
191glEnable(GL_LIGHT0);
192glEnable(GL_MAP2_VERTEX_3);
193glEnable(GL_AUTO_NORMAL);
194glEnable(GL_NORMALIZE);
195glColor3f(1,0,0);
196#ifdef DEBUG
197printf("mapmap\n");
198#endif
199
200
201  for(temp = list; temp != NULL; temp = temp->next)
202    bezierPatchDraw(temp, u_reso, v_reso);
203}
204
205
206
207