NURBS2.C

Go to the documentation of this file.
00001 /* --
00002 OpenFX version 1.0 - Modelling, Animation and Rendering Package
00003 Copyright (C) 2000 OpenFX Development Team
00004 
00005 This program is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU General Public License
00007 as published by the Free Software Foundation; either version 2
00008 of the License, or (at your option) any later version.
00009 
00010 This program is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU General Public License for more details.
00014 
00015 You should have received a copy of the GNU General Public License
00016 along with this program; if not, write to the Free Software
00017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 
00019 You may contact the OpenFX development team via elecronic mail
00020 at core@openfx.org, or visit our website at http://openfx.org for
00021 further information and support details.
00022 -- */
00023 
00024 // File  NURBS2.C  included in NURBS.C
00025 
00026 #include "hidden.h"
00027 
00028 static long hGranularityU=15,hGranularityV=15;
00029 
00030 void HiddenGetNurbsNumbers(long *NoVertices, long *NoFaces){
00031  nurbs *n;
00032  long Vc=0,Fc=0;
00033  if(Nnurbs == 0 || MainNp == NULL)return;
00034  n=MainNp; while(n != NULL){
00035    if(!n->properties.hidden){//n->selected){
00036      Vc += (hGranularityU+1)*(hGranularityV+1);
00037      Fc += (hGranularityU*hGranularityV*2);
00038    }
00039    n=n->last;
00040  }
00041  *NoVertices += Vc;
00042  *NoFaces += Fc;
00043  return;
00044 }
00045 
00046 void HiddenAddNurbsVertices(long *Vcount, void *Vbase, double scale,
00047                             double trr[4][4],
00048                             long XMAX, long YMAX,
00049                             long Xcentre, long Ycentre){
00050  rvertex *v;
00051  nurbs *n;
00052  register long i,j,id;
00053  NurbsSurfSample **pts;
00054  double x,y,z;
00055  v=(rvertex *)Vbase;
00056  if(Nnurbs == 0 || MainNp == NULL)return;
00057  n=MainNp; while(n != NULL){
00058    if(!n->properties.hidden){//n->selected){
00059      if((pts=CreateSurfaceNet(n,hGranularityU,hGranularityV)) == NULL)return;
00060      for(i = 0; i <= hGranularityV; i++)
00061      for(j = 0; j <= hGranularityU; j++){
00062         x=pts[i][j].point[0];
00063         y=pts[i][j].point[1];
00064         z=pts[i][j].point[2];
00065         m4by1(trr,x,y,z,&x,&y,&z);
00066         id = *Vcount;
00067         v[id].p[0]=x;
00068         v[id].p[1]=y;
00069         v[id].p[2]=z;
00070         if(y >= 0.0){
00071           v[id].x=Xcentre+scale*x;
00072           v[id].y=Ycentre-scale*z;
00073         }
00074         else {v[id].x = 0; v[id].y= 0;}
00075         (*Vcount)++;
00076      }
00077      X__Free(pts[0]);
00078      X__Free(pts);
00079    }
00080    n=n->last;
00081  }
00082  return;
00083 }
00084 
00085 void HiddenAddNurbsFaces(long *nF, void *Fb, long Vf){
00086  rface *Fbase;
00087  nurbs *n;
00088  register long i,j;
00089  long x,y,z;
00090  Fbase=(rface *)Fb;
00091  if(Nnurbs == 0 || MainNp == NULL)return;
00092  n=MainNp; while(n != NULL){
00093    if(!n->properties.hidden){//n->selected){
00094      for(i = 0; i < hGranularityV; i++)
00095      for(j = 0; j < hGranularityU; j++){
00096        Fbase[*nF].V[0]=Vf+i*(hGranularityU+1)+j;
00097        Fbase[*nF].V[1]=Vf+(i+1)*(hGranularityU+1)+j;
00098        Fbase[*nF].V[2]=Vf+(i+1)*(hGranularityU+1)+j+1;
00099        (*nF)++;
00100        Fbase[*nF].V[0]=Vf+i*(hGranularityU+1)+j;
00101        Fbase[*nF].V[1]=Vf+(i+1)*(hGranularityU+1)+j+1;
00102        Fbase[*nF].V[2]=Vf+i*(hGranularityU+1)+j+1;
00103        (*nF)++;
00104      }
00105      Vf += (hGranularityU+1)*(hGranularityV+1);
00106    }
00107    n=n->last;
00108  }
00109  return;
00110 }
00111 
00112 typedef struct tagNURBSEDGELIST {
00113  long e[3];
00114 } NURBSEDGELIST;
00115 
00116 typedef struct tagVERTEXEDGELIST {
00117  long ne;
00118  long *e;
00119 } VERTEXEDGELIST;
00120 
00121 static BOOL InNurbsVertexList(long, VERTEXEDGELIST *);
00122 
00123 static long NurbsFirstVertex=0,NurbsFirstEdge=0,NurbsFirstFace=0,
00124             NurbsEdgeListCount=0;
00125 static NURBSEDGELIST *NurbsEdgeList=NULL;
00126 
00127 static void EmitTriangles(nurbs *n){
00128 /*
00129  * Turn a sufficiently flat surface into triangles.
00130  */
00131  vector vecnn,vec0n;        /* Diagonal vectors */
00132  double len2nn,len20n;      /* Diagonal lengths squared */
00133  double u0,un,v0,vn;        /* Texture coords; */
00134  long i,Fv,Fe;
00135  vertex *Vp;
00136  /*
00137   * Measure the distance along the two diagonals to decide the best
00138   * way to cut the rectangle into triangles.
00139   */
00140  VECSUB(n->c00.point,n->cnn.point,vecnn)
00141  VECSUB(n->c0n.point,n->cn0.point,vec0n)
00142  len2nn=(vecnn[0]*vecnn[0]+vecnn[1]*vecnn[1]+vecnn[2]*vecnn[2]);
00143  len20n=(vec0n[0]*vec0n[0]+vec0n[1]*vec0n[1]+vec0n[2]*vec0n[2]);
00144  if(max(len2nn,len20n) < EPSILON)return;
00145  /*
00146   * Assign the texture coordinates
00147   */
00148  u0 = n->kvU[n->orderU-1L];
00149  un = n->kvU[n->numU];
00150  v0 = n->kvV[n->orderV-1L];
00151  vn = n->kvV[n->numV];
00152  n->c00.u = u0; n->c00.v = v0;
00153  n->c0n.u = un; n->c0n.v = v0;
00154  n->cn0.u = u0; n->cn0.v = vn;
00155  n->cnn.u = un; n->cnn.v = vn;
00156  /*
00157   * If any normals are sick, fix them now.
00158   */
00159  if((n->c00.normLen == 0.0) ||
00160     (n->cnn.normLen == 0.0) ||
00161     (n->cn0.normLen == 0.0)){
00162    FixNormals(&(n->c00),&(n->cnn),&(n->cn0));
00163  }
00164  if(n->c0n.normLen == 0.0){
00165    FixNormals(&(n->c00),&(n->c0n),&(n->cnn));
00166  }
00167  if(NurbsEdgeList == NULL)
00168    NurbsEdgeList=(NURBSEDGELIST *)X__Malloc(2*sizeof(NURBSEDGELIST));
00169  else
00170    NurbsEdgeList=(NURBSEDGELIST *)X__Realloc(NurbsEdgeList,
00171                  (NurbsEdgeListCount+2)*sizeof(NURBSEDGELIST));
00172  if(NurbsEdgeList == NULL)return;
00173  if(UpdateVertexHeap(Nvert+4)){
00174    if(UpdateEdgeHeap(Nedge+5)){
00175      if(UpdateFaceHeap(Nface+2)){
00176        Fv=Nvert;
00177        Fe=Nedge;
00178        for(i=0;i<4;i++)CreateVertex();
00179        Vp=(MainVp+Fv);
00180        Vp->xyz[0]=(long)n->c00.point[0];
00181        Vp->xyz[1]=(long)n->c00.point[1];
00182        Vp->xyz[2]=(long)n->c00.point[2];
00183        Vp->gp=1; 
00184        Vp->x=n->c00.u; Vp->y=n->c00.v;
00185        Vp=(MainVp+Fv+1);
00186        Vp->xyz[0]=(long)n->cn0.point[0];
00187        Vp->xyz[1]=(long)n->cn0.point[1];
00188        Vp->xyz[2]=(long)n->cn0.point[2];
00189        Vp->gp=1;
00190        Vp->x=n->cn0.u; Vp->y=n->cn0.v;
00191        Vp=(MainVp+Fv+2);
00192        Vp->xyz[0]=(long)n->cnn.point[0];
00193        Vp->xyz[1]=(long)n->cnn.point[1];
00194        Vp->xyz[2]=(long)n->cnn.point[2];
00195        Vp->gp=1;
00196        Vp->x=n->cnn.u; Vp->y=n->cnn.v;
00197        Vp=(MainVp+Fv+3);
00198        Vp->xyz[0]=(long)n->c0n.point[0];
00199        Vp->xyz[1]=(long)n->c0n.point[1];
00200        Vp->xyz[2]=(long)n->c0n.point[2];
00201        Vp->gp=1;
00202        Vp->x=n->c0n.u; Vp->y=n->c0n.v;
00203        CreateEdge(Fv+0,Fv+1);
00204        CreateEdge(Fv+1,Fv+2);
00205        CreateEdge(Fv+2,Fv+3);
00206        CreateEdge(Fv+3,Fv+0);
00207        if(len2nn < len20n){
00208          CreateEdge(Fv+0,Fv+2);
00209          CreateFace(Fv+0,Fv+2,Fv+1);
00210          CreateFace(Fv+0,Fv+3,Fv+2);
00211          NurbsEdgeList[NurbsEdgeListCount].e[0]=Fe+1;
00212          NurbsEdgeList[NurbsEdgeListCount].e[1]=Fe+0;
00213          NurbsEdgeList[NurbsEdgeListCount].e[2]=Fe+4;
00214          NurbsEdgeListCount++;
00215          NurbsEdgeList[NurbsEdgeListCount].e[0]=Fe+2;
00216          NurbsEdgeList[NurbsEdgeListCount].e[1]=Fe+4;
00217          NurbsEdgeList[NurbsEdgeListCount].e[2]=Fe+3;
00218          NurbsEdgeListCount++;
00219        }
00220        else{
00221          CreateEdge(Fv+3,Fv+1);
00222          CreateFace(Fv+0,Fv+3,Fv+1);
00223          CreateFace(Fv+3,Fv+2,Fv+1);
00224          NurbsEdgeList[NurbsEdgeListCount].e[0]=Fe+4;
00225          NurbsEdgeList[NurbsEdgeListCount].e[1]=Fe+0;
00226          NurbsEdgeList[NurbsEdgeListCount].e[2]=Fe+3;
00227          NurbsEdgeListCount++;
00228          NurbsEdgeList[NurbsEdgeListCount].e[0]=Fe+1;
00229          NurbsEdgeList[NurbsEdgeListCount].e[1]=Fe+4;
00230          NurbsEdgeList[NurbsEdgeListCount].e[2]=Fe+2;
00231          NurbsEdgeListCount++;
00232        }
00233      }
00234    }
00235  }
00236  return;
00237 }
00238 
00239 static BOOL SameVertexLocation(vertex *vp, vertex *vpp){
00240  long tolerance=MINUNIT/32;
00241  if(labs(vp->xyz[0] - vpp->xyz[0]) < tolerance &&
00242     labs(vp->xyz[1] - vpp->xyz[1]) < tolerance &&
00243     labs(vp->xyz[2] - vpp->xyz[2]) < tolerance)return TRUE;
00244  return FALSE;
00245 }
00246 
00247 static void NurbsEliminateDuplicateVertices(void){
00248  BOOL removed=FALSE;
00249  vertex *vp,*vpp,*vo;
00250  edge   *ep;
00251  face   *fp;
00252  long i,j,k,NewC;
00253  for(vp=(MainVp+NurbsFirstVertex),i=NurbsFirstVertex;i<Nvert;i++,vp++)vp->id = -1;
00254  for(i=NurbsFirstVertex;i<Nvert-1;i++){
00255    vp=(MainVp+i);
00256    if(vp->id < 0){
00257      for(j=i+1;j<Nvert;j++){
00258        vpp=(MainVp+j);
00259        if(vpp->id < 0 && SameVertexLocation(vp,vpp))vpp->id=i;
00260      }
00261    }
00262  }
00263  for(ep=(MainEp+NurbsFirstEdge),i=NurbsFirstEdge;i<Nedge;i++,ep++){
00264    if((j=(MainVp+ep->V[0])->id) >= 0)ep->V[0]=j;
00265    if((j=(MainVp+ep->V[1])->id) >= 0)ep->V[1]=j;
00266  }
00267  for(fp=(MainFp+NurbsFirstFace),i=NurbsFirstFace;i<Nface;i++,fp++){
00268    if((j=(MainVp+fp->V[0])->id) >= 0)fp->V[0]=j;
00269    if((j=(MainVp+fp->V[1])->id) >= 0)fp->V[1]=j;
00270    if((j=(MainVp+fp->V[2])->id) >= 0)fp->V[2]=j;
00271  }
00272  for(vp=(MainVp+NurbsFirstVertex),i=NurbsFirstVertex;i<Nvert;i++,vp++){
00273    if(vp->id >= 0){
00274      vp->status=INEDITOR;
00275      removed=TRUE;
00276      NvertSelect--;
00277    }
00278    vp->id = 0;
00279  }
00280  NewC=Nvert;
00281  vp=(MainVp+NurbsFirstVertex);
00282  for(i=NurbsFirstVertex,k=NurbsFirstVertex;i<Nvert;i++){
00283    if(vp->status == INEDITOR){
00284      if(i < Nvert-1){
00285        vo=(MainVp+NewC-1);
00286        CopyMemory(vp,vo,sizeof(vertex));
00287        vo->id=k;
00288      }
00289      NewC--;
00290    }
00291    else {
00292      vp++; k++;
00293    }
00294  }
00295  if(NewC < Nvert){
00296    Nvert=NewC;
00297    for(i=NurbsFirstFace,fp=(MainFp+NurbsFirstFace);i<Nface;i++,fp++){
00298      if(fp->V[0] >= Nvert)fp->V[0]=(MainVp+fp->V[0])->id;
00299      if(fp->V[1] >= Nvert)fp->V[1]=(MainVp+fp->V[1])->id;
00300      if(fp->V[2] >= Nvert)fp->V[2]=(MainVp+fp->V[2])->id;
00301    }
00302    for(i=NurbsFirstEdge,ep=(MainEp+NurbsFirstEdge);i<Nedge;i++,ep++){
00303      if(ep->V[0] >= Nvert)ep->V[0]=(MainVp+ep->V[0])->id;
00304      if(ep->V[1] >= Nvert)ep->V[1]=(MainVp+ep->V[1])->id;
00305    }
00306    UpdateVertexHeap(Nvert);
00307  }
00308  else if(removed)MessageBox(NULL,"Warning 1",NULL,MB_OK);
00309  return;
00310 }
00311 
00312 static BOOL VertexOnEdge(vertex *vp, edge *ep){
00313  double tolerance=(double)MINUNIT/32.0;
00314  double l,l01,d;
00315  vector pi,p01;
00316  VECSUB((double)vp->xyz,(double)(MainVp+ep->V[0])->xyz,pi)
00317  VECSUB((double)(MainVp+ep->V[1])->xyz,(double)(MainVp+ep->V[0])->xyz,p01)
00318  l01=sqrt(p01[0]*p01[0]+p01[1]*p01[1]+p01[2]*p01[2]);
00319  if(fabs(l01) < 0.01)return FALSE;
00320  p01[0] /= l01; p01[1] /= l01; p01[2] /= l01;
00321  l=DOT(pi,p01);
00322  if(l < 0.0 || l > l01)return FALSE;
00323  d=sqrt((pi[0]-l*p01[0])*(pi[0]-l*p01[0])+
00324         (pi[1]-l*p01[1])*(pi[1]-l*p01[1])+
00325         (pi[2]-l*p01[2])*(pi[2]-l*p01[2]));
00326  if(d < tolerance)return TRUE;
00327  return FALSE;
00328 }
00329 
00330 static void NurbsInsertDividingEdges(void){
00331  vertex *vp;
00332  face *fp;
00333  long i,j,k,movedV,movedE;
00334  edge *e0,*e1,*e2;
00335  LOOP:
00336  for(i=NurbsFirstFace,fp=(MainFp+NurbsFirstFace),k=0;i<Nface;i++,fp++,k++){
00337    e0=(MainEp+NurbsEdgeList[k].e[0]);
00338    e1=(MainEp+NurbsEdgeList[k].e[1]);
00339    e2=(MainEp+NurbsEdgeList[k].e[2]);
00340    for(vp=(MainVp+NurbsFirstVertex),j=NurbsFirstVertex;j<Nvert;j++,vp++){
00341      if(j != fp->V[0] && j != fp->V[1] && j != fp->V[2]){
00342        if(VertexOnEdge(vp,e0)){
00343          movedV=fp->V[2];
00344          fp->V[2]=j;
00345          e0->V[0]=fp->V[1];
00346          e0->V[1]=j;
00347          if(!UpdateEdgeHeap(Nedge+2))return;
00348          CreateEdge(fp->V[0],j);
00349          movedE=NurbsEdgeList[k].e[1];
00350          NurbsEdgeList[k].e[1]=(Nedge-1);
00351          CreateEdge(j,movedV);
00352          if(!UpdateFaceHeap(Nface+1))return;
00353          CreateFace(fp->V[0],j,movedV);
00354          CopyFaceProp(fp,(MainFp+Nface-1));
00355          NurbsEdgeList=(NURBSEDGELIST *)X__Realloc(NurbsEdgeList,
00356            (NurbsEdgeListCount+1)*sizeof(NURBSEDGELIST));
00357          if(NurbsEdgeList == NULL)return;
00358          NurbsEdgeList[NurbsEdgeListCount].e[0]=Nedge-1;
00359          NurbsEdgeList[NurbsEdgeListCount].e[1]=movedE;
00360          NurbsEdgeList[NurbsEdgeListCount].e[2]=Nedge-2;
00361          NurbsEdgeListCount++;
00362          goto LOOP;
00363        }
00364        if(VertexOnEdge(vp,e1)){
00365          movedV=fp->V[0];
00366          fp->V[0]=j;
00367          e1->V[0]=fp->V[2];
00368          e1->V[1]=j;
00369          if(!UpdateEdgeHeap(Nedge+2))return;
00370          CreateEdge(fp->V[1],j);
00371          movedE=NurbsEdgeList[k].e[2];
00372          NurbsEdgeList[k].e[2]=(Nedge-1);
00373          CreateEdge(j,movedV);
00374          if(!UpdateFaceHeap(Nface+1))return;
00375          CreateFace(fp->V[1],j,movedV);
00376          CopyFaceProp(fp,(MainFp+Nface-1));
00377          NurbsEdgeList=(NURBSEDGELIST *)X__Realloc(NurbsEdgeList,
00378            (NurbsEdgeListCount+1)*sizeof(NURBSEDGELIST));
00379          if(NurbsEdgeList == NULL)return;
00380          NurbsEdgeList[NurbsEdgeListCount].e[0]=Nedge-1;
00381          NurbsEdgeList[NurbsEdgeListCount].e[1]=movedE;
00382          NurbsEdgeList[NurbsEdgeListCount].e[2]=Nedge-2;
00383          NurbsEdgeListCount++;
00384          goto LOOP;
00385        }
00386        if(VertexOnEdge(vp,e2)){
00387          movedV=fp->V[1];
00388          fp->V[1]=j;
00389          e2->V[0]=fp->V[0];
00390          e2->V[1]=j;
00391          if(!UpdateEdgeHeap(Nedge+2))return;
00392          CreateEdge(fp->V[2],j);
00393          movedE=NurbsEdgeList[k].e[0];
00394          NurbsEdgeList[k].e[0]=(Nedge-1);
00395          CreateEdge(j,movedV);
00396          if(!UpdateFaceHeap(Nface+1))return;
00397          CreateFace(fp->V[2],j,movedV);
00398          CopyFaceProp(fp,(MainFp+Nface-1));
00399          NurbsEdgeList=(NURBSEDGELIST *)X__Realloc(NurbsEdgeList,
00400            (NurbsEdgeListCount+1)*sizeof(NURBSEDGELIST));
00401          if(NurbsEdgeList == NULL)return;
00402          NurbsEdgeList[NurbsEdgeListCount].e[0]=Nedge-1;
00403          NurbsEdgeList[NurbsEdgeListCount].e[1]=movedE;
00404          NurbsEdgeList[NurbsEdgeListCount].e[2]=Nedge-2;
00405          NurbsEdgeListCount++;
00406          goto LOOP;
00407        }
00408      }
00409    }
00410  }
00411  return;
00412 }
00413 
00414 static BOOL InNurbsVertexList(long v, VERTEXEDGELIST *vl){
00415  long i;
00416  for(i=0;i<vl->ne;i++){
00417    if(vl->e[i] == v)return TRUE;
00418  }
00419  return FALSE;
00420 }
00421 
00422 static void NurbsEliminateDuplicateEdges(void){
00423  VERTEXEDGELIST *VertexEdgeList=NULL;
00424  long i,v0,v1,ne,NewC;
00425  edge *ep;
00426  if((VertexEdgeList=(VERTEXEDGELIST *)X__Malloc(sizeof(VERTEXEDGELIST)*
00427    (Nvert-NurbsFirstVertex))) == NULL)return;
00428  for(i=0;i<Nvert-NurbsFirstVertex;i++){
00429   VertexEdgeList[i].ne=0;
00430   VertexEdgeList[i].e=NULL;
00431  }
00432  for(i=NurbsFirstEdge;i<Nedge;i++){
00433    v0=((MainEp+i)->V[0])-NurbsFirstVertex;
00434    v1=((MainEp+i)->V[1])-NurbsFirstVertex;
00435    if(v0 < 0 || v1 < 0)MessageBox(NULL,"BAD vertices",NULL,MB_OK);
00436    if(VertexEdgeList[v0].e != NULL && VertexEdgeList[v0].ne > 0){
00437      if(InNurbsVertexList(v1,&VertexEdgeList[v0])){ // duplicate mark for delete
00438        (MainEp+i)->V[0] = -1;
00439        (MainEp+i)->V[1] = -1;
00440      }
00441      else{ // add to list
00442        ne=VertexEdgeList[v0].ne;
00443        if((VertexEdgeList[v0].e=(long *)X__Realloc(VertexEdgeList[v0].e,
00444                                         sizeof(long)*(ne+1))) != NULL){
00445          VertexEdgeList[v0].e[ne]=v1;
00446          VertexEdgeList[v0].ne=ne+1;
00447        }
00448      }
00449    }
00450    else{ // start new list
00451      if((VertexEdgeList[v0].e=(long *)X__Malloc(sizeof(long))) != NULL){
00452        VertexEdgeList[v0].e[0]=v1;
00453        VertexEdgeList[v0].ne=1;
00454      }
00455    }
00456    if(VertexEdgeList[v1].e != NULL && VertexEdgeList[v1].ne > 0){
00457      if(InNurbsVertexList(v0,&VertexEdgeList[v1])){ // duplicate mark for delete
00458        (MainEp+i)->V[0] = -1;
00459        (MainEp+i)->V[1] = -1;
00460      }
00461      else{ // add to list
00462        ne=VertexEdgeList[v1].ne;
00463        if((VertexEdgeList[v1].e=(long *)X__Realloc(VertexEdgeList[v1].e,
00464                                         sizeof(long)*(ne+1))) != NULL){
00465          VertexEdgeList[v1].e[ne]=v0;
00466          VertexEdgeList[v1].ne=ne+1;
00467        }
00468      }
00469    }
00470    else{ // start new list
00471      if((VertexEdgeList[v1].e=(long *)X__Malloc(sizeof(long))) != NULL){
00472        VertexEdgeList[v1].e[0]=v0;
00473        VertexEdgeList[v1].ne=1;
00474      }
00475    }
00476  }
00477  NewC=Nedge; // eliminate duplicate edges
00478  for(ep=(MainEp+NurbsFirstEdge),i=NurbsFirstEdge;i<Nedge;i++){
00479    if(ep->V[0] < 0 || ep->V[1] < 0){
00480      if(i < Nedge-1)CopyMemory(ep,(MainEp+NewC-1),sizeof(edge));
00481      NewC--;
00482    }
00483    else ep++;
00484  }
00485  if(NewC != Nedge){
00486    Nedge=NewC;
00487    UpdateEdgeHeap(Nedge);
00488  }
00489  for(ep=MainEp,i=0;i<Nedge;i++,ep++){
00490    if(ep->V[0] < 0 || ep->V[1] < 0)MessageBox(NULL,"BAD Edges",NULL,MB_OK);
00491  }
00492  for(i=0;i<Nvert-NurbsFirstVertex;i++){
00493    if(VertexEdgeList[i].e != NULL)X__Free(VertexEdgeList[i].e);
00494  }
00495  X__Free(VertexEdgeList);
00496  return;
00497 }
00498 
00499 void MeshNurbsSurface(void){
00500  HCURSOR hCursorSave;
00501  long i=500;
00502  nurbs *n;
00503  if(Nnurbs == 0 || MainNp == NULL)return;
00504  if((i=RequestNumEntry((short)i,1,10000,"Tesselate","Resolution")) < 0)return;
00505  hCursorSave=SetCursor(ghcurWait);
00506  SubdivTolerance=((double)MINUNIT)*(double)(i)/1000.0;
00507  n=MainNp; while(n != NULL){
00508    if(n->selected && !n->properties.hidden){
00509      NurbsFirstVertex=Nvert;
00510      NurbsFirstEdge=Nedge;
00511      NurbsFirstFace=Nface;
00512      NurbsEdgeListCount=0;
00513      NurbsEdgeList=NULL;
00514      EmitSubdivision(n);
00515      NurbsEliminateDuplicateVertices();
00516      NurbsInsertDividingEdges();
00517      NurbsEliminateDuplicateEdges();
00518      if(NurbsEdgeList != NULL)X__Free(NurbsEdgeList);
00519    }
00520    n=n->last;
00521  }
00522  SetCursor(hCursorSave);
00523  DrawModel();
00524  return;
00525 }
00526 
00527 #include "faceattr.h"
00528 
00529 void PutNurbsAttribute(int what, void *ff){
00530  /* The IDs are the same as for the face attributes */
00531  nurbs *np;
00532  NurbsProperties *fp;
00533  FACEATTRIBS *f;
00534  f=(FACEATTRIBS *)ff;
00535  if(Nnurbs == 0 || MainNp == NULL)return;
00536  np=MainNp; while(np != NULL){
00537    if(np->selected){
00538      fp = &(np->properties);
00539      if(what == 0){
00540        VECCOPY(f->fc,fp->colour)
00541      }
00542      else if(what == 5){ /* smoothing */
00543        if(f->sm == 1)fp->smoothing=1;
00544        else          fp->smoothing=0;
00545      }
00546      else if(what == 7){ /* set shader value */
00547        fp->shader = (long)f->sh;
00548      }
00549      else if(what == 8){ /* dump map - clear bit 6 */
00550        fp->map = -1;
00551      }
00552      else if(what == 9){ /* set shader axis ID */
00553        fp->axis  = (long)f->sa;
00554      }
00555      else if(what == 10){ /* set map */
00556        fp->map    = (long)f->bu;
00557      }
00558    }
00559    np=np->last;
00560  }
00561  return;
00562 }
00563 
00564 void WriteNurbs(FILE *fo){
00565  long i,j;
00566  nurbs *n,*first;
00567 //{ char ttt[256];
00568 //sprintf(ttt,"size of prop %ld  vec4=%ld vec=%ld BOOL=%ld uc=%ld",
00569 //sizeof(NurbsProperties),
00570 //sizeof(vector4),sizeof(vector),
00571 //sizeof(BOOL),sizeof(unsigned char));
00572 //MessageBox(NULL,ttt,"Write",MB_OK);
00573 //}
00574  if(Nnurbs == 0 || MainNp == NULL)return;
00575  n=MainNp; while(n != NULL){
00576    first=n;
00577    n=n->last;
00578  }
00579  n=first;
00580  fwrite(&Nnurbs,sizeof(long),1,fo);
00581  while(n != NULL){
00582    fwrite(&(n->properties),sizeof(NurbsProperties),1,fo);
00583    fwrite(&(n->numU),sizeof(long),1,fo);
00584    fwrite(&(n->numV),sizeof(long),1,fo);
00585    fwrite(&(n->orderU),sizeof(long),1,fo);
00586    fwrite(&(n->orderV),sizeof(long),1,fo);
00587    for(i=0;i<n->numU + n->orderU; i++)fwrite(&(n->kvU[i]),sizeof(double),1,fo);
00588    for(i=0;i<n->numV + n->orderV; i++)fwrite(&(n->kvV[i]),sizeof(double),1,fo);
00589    for(i=0;i<n->numV; i++)
00590    for(j=0;j<n->numU; j++){
00591      fwrite(&(n->points[i][j]),sizeof(vector4),1,fo);
00592    }
00593    n=n->next;
00594  }
00595  return;
00596 }
00597 
00598 void ReadNurbs(long clen, short relation, HANDLE fq){
00599  DWORD dwRead;
00600  nurbs *n;
00601  long i,j,k,N;
00602  ReadFile(fq,&N,sizeof(long),&dwRead,NULL);
00603  for(k=0;k<N;k++){
00604    CreateNurbs();
00605    n=MainNp;
00606    if(n != NULL){
00607      ReadFile(fq,&(n->properties),sizeof(NurbsProperties),&dwRead,NULL);
00608      ReadFile(fq,&(n->numU),sizeof(long),&dwRead,NULL);
00609      ReadFile(fq,&(n->numV),sizeof(long),&dwRead,NULL);
00610      ReadFile(fq,&(n->orderU),sizeof(long),&dwRead,NULL);
00611      ReadFile(fq,&(n->orderV),sizeof(long),&dwRead,NULL);
00612      AllocNurbs(n,NULL,NULL);
00613      for(i=0;i<n->numU + n->orderU; i++)
00614        ReadFile(fq,&(n->kvU[i]),sizeof(double),&dwRead,NULL);
00615      for(i=0;i<n->numV + n->orderV; i++)
00616        ReadFile(fq,&(n->kvV[i]),sizeof(double),&dwRead,NULL);
00617      for(i=0;i<n->numV; i++)
00618      for(j=0;j<n->numU; j++){
00619        ReadFile(fq,&(n->points[i][j]),sizeof(vector4),&dwRead,NULL);
00620      }
00621    }
00622  }
00623  return;
00624 }
00625 

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