00001
00002
00003 #define MODULE_NURBS
00004
00005 #include "render.h"
00006
00007 #define MAXORDER 20
00008
00009 static double SubdivTolerance=(double)1024;
00010
00011 static void EmitTriangles(nurbs *);
00012 static BOOL NurbsSameVertexLocation(vertex *, vertex *);
00013 static void NurbsEliminateDuplicateVertices(void);
00014
00015 static void ReleaseNurbs(nurbs *n){
00016 long i;
00017 if(n->kvU != NULL)X__Free(n->kvU);
00018 n->kvU = NULL;
00019 if(n->kvV != NULL)X__Free(n->kvV);
00020 n->kvV = NULL;
00021 if(n->points == NULL)return;
00022 for(i=0;i < n->numV;i++)X__Free(n->points[i]);
00023 X__Free(n->points);
00024 n->points=NULL;
00025 return;
00026 }
00027
00028 BOOL AllocNurbs(nurbs *n, double *ukv, double *vkv){
00029 long i;
00030 if(ukv == NULL){
00031 if((n->kvU = (double *)X__Malloc((n->numU + n->orderU) * sizeof(double)))
00032 == NULL)return FALSE;
00033 }
00034 else n->kvU = ukv;
00035 if(vkv == NULL){
00036 if((n->kvV = (double *)X__Malloc((n->numV + n->orderV) * sizeof(double)))
00037 == NULL)return FALSE;
00038 }
00039 else n->kvV = vkv;
00040 if((n->points = (vector4 **)X__Malloc((long)n->numV
00041 * (long)sizeof(vector4 *))) == NULL)return FALSE;
00042 for (i = 0; i < n->numV; i++){
00043 if((n->points[i] = (vector4 *)X__Malloc((long)n->numU
00044 * (long)sizeof(vector4))) == NULL)return FALSE;
00045 }
00046 return TRUE;
00047 }
00048
00049 void FreeNurbs(long n, nurbs *Np){
00050 long i;
00051 if(n == 0 || Np == NULL)return;
00052 for(i=0;i<n;i++){
00053 ReleaseNurbs((Np+i));
00054 }
00055 X__Free(Np);
00056 return;
00057 }
00058
00059 #include "..\common\design\nurbs1.c"
00060
00061 static object *ObjectPointer=NULL;
00062 static nurbs *thisNurbs;
00063 static long NurbsFirstVertex,NurbsFirstFace,NonNurbsVertices;
00064
00065 static void EmitTriangles(nurbs *n){
00066 BOOL no_vertices;
00067 vertex *Vbase=NULL;
00068 face *Fbase=NULL;
00069 long Nv,Nt,Nf;
00070 vector vecnn,vec0n;
00071 double len2nn,len20n;
00072 double u0,un,v0,vn;
00073 VECSUB(n->c00.point,n->cnn.point,vecnn)
00074 VECSUB(n->c0n.point,n->cn0.point,vec0n)
00075 len2nn=(vecnn[0]*vecnn[0]+vecnn[1]*vecnn[1]+vecnn[2]*vecnn[2]);
00076 len20n=(vec0n[0]*vec0n[0]+vec0n[1]*vec0n[1]+vec0n[2]*vec0n[2]);
00077 if(max(len2nn,len20n) < EPSILON)return;
00078 u0 = n->kvU[n->orderU-1L];
00079 un = n->kvU[n->numU];
00080 v0 = n->kvV[n->orderV-1L];
00081 vn = n->kvV[n->numV];
00082 n->c00.u = u0; n->c00.v = v0;
00083 n->c0n.u = un; n->c0n.v = v0;
00084 n->cn0.u = u0; n->cn0.v = vn;
00085 n->cnn.u = un; n->cnn.v = vn;
00086 if((n->c00.normLen == 0.0) ||
00087 (n->cnn.normLen == 0.0) ||
00088 (n->cn0.normLen == 0.0)){
00089 FixNormals(&(n->c00),&(n->cnn),&(n->cn0));
00090 }
00091 if(n->c0n.normLen == 0.0){
00092 FixNormals(&(n->c00),&(n->c0n),&(n->cnn));
00093 }
00094
00095 Nv=ObjectPointer->NoVertices;
00096 if(ObjectPointer->Vbase == NULL){
00097 Vbase=(vertex *)X__Malloc(4*sizeof(vertex));
00098 }
00099 else{
00100 Vbase=(vertex *)X__Realloc(ObjectPointer->Vbase,(Nv+4)*sizeof(vertex));
00101 }
00102 if(Vbase != NULL){
00103 ObjectPointer->NoVertices=Nv+4;
00104 ObjectPointer->Vbase=Vbase;
00105 }
00106 else return;
00107 if(NonNurbsVertices == 0 || ObjectPointer->Vbase != NULL){
00108 (Vbase+Nv )->u=n->c00.u; (Vbase+Nv )->v=n->c00.v;
00109 (Vbase+Nv+1)->u=n->cn0.u; (Vbase+Nv+1)->v=n->cn0.v;
00110 (Vbase+Nv+2)->u=n->cnn.u; (Vbase+Nv+2)->v=n->cnn.v;
00111 (Vbase+Nv+3)->u=n->c0n.u; (Vbase+Nv+3)->v=n->c0n.v;
00112 }
00113 VECCOPY(n->c00.point,(Vbase+Nv )->p)
00114 VECCOPY(n->cn0.point,(Vbase+Nv+1)->p)
00115 VECCOPY(n->cnn.point,(Vbase+Nv+2)->p)
00116 VECCOPY(n->c0n.point,(Vbase+Nv+3)->p)
00117 Nf=ObjectPointer->NoFaces;
00118 if(ObjectPointer->Fbase == NULL){
00119 Fbase=(face *)X__Malloc(2*sizeof(face ));
00120 }
00121 else{
00122 Fbase=(face *)X__Realloc(ObjectPointer->Fbase,(Nf+2)*sizeof(face ));
00123 }
00124 if(Fbase != NULL){
00125 ObjectPointer->NoFaces=Nf+2;
00126 ObjectPointer->Fbase=Fbase;
00127 }
00128 else return;
00129 memset((Fbase+Nf ),0,sizeof(face));
00130 memset((Fbase+Nf+1),0,sizeof(face));
00131 if(len2nn < len20n){
00132 (Fbase+Nf)->V[0]=Nv;
00133 (Fbase+Nf)->V[1]=Nv+2;
00134 (Fbase+Nf)->V[2]=Nv+1;
00135 (Fbase+Nf+1)->V[0]=Nv;
00136 (Fbase+Nf+1)->V[1]=Nv+3;
00137 (Fbase+Nf+1)->V[2]=Nv+2;
00138 }
00139 else{
00140 (Fbase+Nf)->V[0]=Nv;
00141 (Fbase+Nf)->V[1]=Nv+3;
00142 (Fbase+Nf)->V[2]=Nv+1;
00143 (Fbase+Nf+1)->V[0]=Nv+3;
00144 (Fbase+Nf+1)->V[1]=Nv+2;
00145 (Fbase+Nf+1)->V[2]=Nv+1;
00146 }
00147 VECCOPY(thisNurbs->properties.colour,(Fbase+Nf )->color)
00148 VECCOPY(thisNurbs->properties.colour,(Fbase+Nf+1)->color)
00149 (Fbase+Nf )->bSmooth=TRUE;
00150 (Fbase+Nf+1)->bSmooth=TRUE;
00151 return;
00152 }
00153
00154 static BOOL NurbsSameVertexLocation(vertex *vp, vertex *vpp){
00155 long tolerance=1024/32;
00156 if(labs(vp->p[0] - vpp->p[0]) < tolerance &&
00157 labs(vp->p[1] - vpp->p[1]) < tolerance &&
00158 labs(vp->p[2] - vpp->p[2]) < tolerance)return TRUE;
00159 return FALSE;
00160 }
00161
00162 static void NurbsEliminateDuplicateVertices(void){
00163 BOOL removed=FALSE;
00164 vertex *vp,*vpp,*vo,*MainVp;
00165 face *fp,*MainFp;
00166 long i,j,k,NewC,Nvert,Nface;
00167 Nvert=ObjectPointer->NoVertices;
00168 Nface=ObjectPointer->NoFaces;
00169 MainVp=ObjectPointer->Vbase;
00170 MainFp=ObjectPointer->Fbase;
00171 for(vp=(MainVp+NurbsFirstVertex),i=NurbsFirstVertex;i<Nvert;i++,vp++){
00172 vp->x = -1.0;
00173 }
00174 for(i=NurbsFirstVertex;i<Nvert-1;i++){
00175 vp=(MainVp+i);
00176 if(vp->x < 0.0){
00177 for(j=i+1;j<Nvert;j++){
00178 vpp=(MainVp+j);
00179 if(vpp->x < 0.0 && NurbsSameVertexLocation(vp,vpp))vpp->x=(double)i;
00180 }
00181 }
00182 }
00183 for(fp=(MainFp+NurbsFirstFace),i=NurbsFirstFace;i<Nface;i++,fp++){
00184 if((j=(long)(MainVp+fp->V[0])->x) >= 0)fp->V[0]=j;
00185 if((j=(long)(MainVp+fp->V[1])->x) >= 0)fp->V[1]=j;
00186 if((j=(long)(MainVp+fp->V[2])->x) >= 0)fp->V[2]=j;
00187 }
00188 for(vp=(MainVp+NurbsFirstVertex),i=NurbsFirstVertex;i<Nvert;i++,vp++){
00189 if(vp->x >= 0.0){
00190 vp->y = 1.0;
00191 removed=TRUE;
00192 }
00193 else vp->y = 0.0;
00194 vp->x = 0.0;
00195 }
00196 NewC=Nvert;
00197 vp=(MainVp+NurbsFirstVertex);
00198 for(i=NurbsFirstVertex,k=NurbsFirstVertex;i<Nvert;i++){
00199 if(vp->y > 0.0){
00200 if(i < Nvert-1){
00201 vo=(MainVp+NewC-1);
00202 CopyMemory(vp,vo,sizeof(vertex));
00203 vo->x=(double)k;
00204 }
00205 NewC--;
00206 }
00207 else {
00208 vp++; k++;
00209 }
00210 }
00211 if(NewC < Nvert){
00212 Nvert=NewC;
00213 for(i=NurbsFirstFace,fp=(MainFp+NurbsFirstFace);i<Nface;i++,fp++){
00214 if(fp->V[0] >= Nvert)fp->V[0]=(UNSIGNED)(MainVp+fp->V[0])->x;
00215 if(fp->V[1] >= Nvert)fp->V[1]=(UNSIGNED)(MainVp+fp->V[1])->x;
00216 if(fp->V[2] >= Nvert)fp->V[2]=(UNSIGNED)(MainVp+fp->V[2])->x;
00217 }
00218 MainVp=(vertex *)X__Realloc(ObjectPointer->Vbase,(Nvert)*sizeof(vertex));
00219 if(MainVp != NULL){
00220 ObjectPointer->NoVertices=Nvert;
00221 ObjectPointer->Vbase=MainVp;
00222 }
00223 }
00224 else if(removed)MessageBox(NULL,"Warning 1",NULL,MB_OK);
00225 for(vp=(MainVp+NurbsFirstVertex),i=NurbsFirstVertex;i<Nvert;i++,vp++){
00226 vp->x = vp->y = 0.0;
00227 }
00228 return;
00229 }
00230
00231 BOOL MeshNurbsSurfaces(long oid){
00232 nurbs *Np;
00233 long i,n;
00234 ObjectPointer=(Object+oid);
00235 NonNurbsVertices=ObjectPointer->NoVertices;
00236 Np=ObjectPointer->Nbase;
00237 n=ObjectPointer->NoNurbs;
00238 if(n == 0 || Np == NULL)return FALSE;
00239 for(i=0;i<n;i++){
00240 thisNurbs=(Np+i);
00241 if(thisNurbs->properties.hidden == 0){
00242 NurbsFirstVertex=ObjectPointer->NoVertices;
00243 NurbsFirstFace=ObjectPointer->NoFaces;
00244 EmitSubdivision(thisNurbs);
00245 NurbsEliminateDuplicateVertices();
00246 }
00247 }
00248 return TRUE;
00249 }