NURBS.C

Go to the documentation of this file.
00001 /* file NURBS.C  - for use in the renderer */
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;  // smooth
00150  (Fbase+Nf+1)->bSmooth=TRUE;  // smooth
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 }

Generated on Sun Apr 27 14:20:11 2014 for OpenFX by  doxygen 1.5.6