NURBS.C

Go to the documentation of this file.
00001 /* --
00002 OpenFX - Modelling, Animation and Rendering Package
00003 -- */
00004 
00005 
00006 /* File NURBS.C the nurbs objects */
00007 
00008 #define MODULE_NURBS 1
00009 
00010 #include "design.h"
00011 #include "..\animate\spin_dll.h"
00012 
00013 #define MAXORDER 20
00014 
00015 /* Size of facets produced in adaptive subdivision */
00016 //static double SubdivTolerance=(double)MINUNIT/10;
00017 static double SubdivTolerance=(double)MINUNIT/2;
00018 
00019 static long FindBreakPoint( double, double *, long, long);
00020 static void BasisDerivatives( double, long, double *, long, double *);
00021 static void BasisFunctions( double, long, double *, long, double *);
00022 static void CalcPoint(double, double, nurbs *, vector, vector, vector);
00023 static NurbsSurfSample **CreateSurfaceNet(nurbs *, long, long);
00024 static BOOL DrawNurbsOutline(HDC, int, nurbs *, BOOL);
00025 static void DrawNurbsEdge(HDC, int, NurbsSurfSample *, NurbsSurfSample *);
00026 static void DrawNurbsControlPoints(nurbs *, HDC, int, BOOL);
00027 static void DrawInvertNurbsInOne(nurbs *, int, BOOL);
00028 static void RotateNurbsPoint(double, double, long, long, double *,
00029                              double *, double, double);
00030 static void NurbsTorus(nurbs *, double, double);
00031 static void NurbsBezier(nurbs *, double, double);
00032 static void NurbsTeapot(void);
00033 static BOOL CalcAlpha(double *, double *, long, long, long, double ***);
00034 static void RefineSurface(nurbs *, nurbs *, BOOL);
00035 static long SplitKV(double *, double **, long *, long, long);
00036 static void ProjectToLine(vector, vector, vector);
00037 static void FixNormals(NurbsSurfSample *, NurbsSurfSample *, NurbsSurfSample *);
00038 static void AdjustNormal(NurbsSurfSample *);
00039 static void GetNormal(nurbs *, long, long);
00040 static void MakeNewCorners(nurbs *, nurbs *, nurbs *, BOOL);
00041 static void SplitSurface(nurbs *, nurbs *, nurbs *, BOOL);
00042 static BOOL IsCurveStraight(nurbs *, double, long, BOOL);
00043 static BOOL TestFlat(nurbs *, double);
00044 static void EmitTriangles(nurbs *);
00045 static void DoSubdivision(nurbs *, double, BOOL, long);
00046 static void NurbsEliminateDuplicateVertices(void);
00047 static void NurbsInsertDividingEdges(void);
00048 static void NurbsEliminateDuplicateEdges(void);
00049 static void EmitSubdivision(nurbs *);
00050 static BOOL CheckHitNurbsOutline(int, int, int, NurbsSurfSample *, NurbsSurfSample *);
00051 static BOOL CheckNurbsIn(int, int,
00052                          long, long, long, long, int, int, double, HRGN,
00053                          NurbsSurfSample *,NurbsSurfSample *);
00054 static BOOL SameVertexLocation(vertex *, vertex *);
00055 static BOOL VertexOnEdge(vertex *, edge *);
00056 
00057 #include "nurbsdlg.c"
00058 
00059 void MakeNewNurbsSurface(int type){
00060  if(type == 0){ // basic type
00061    CreateNurbs();
00062    if(!DialogBoxParam(ghinst_main,MAKEINTRESOURCE(DLG_ADDNURBS),ghwnd_main,
00063                      (DLGPROC)AddNurbsDlgProc,(LPARAM)MainNp)){
00064      EraseNurbs(MainNp);
00065    }
00066  }
00067  else if(type == 1){
00068    CreateNurbs();
00069    sprintf(MainNp->properties.name,"Bezier_%ld",Nnurbs);
00070    NurbsBezier(MainNp,10.0,10.0);
00071  }
00072  else if(type == 2){
00073    CreateNurbs();
00074    sprintf(MainNp->properties.name,"Torus_%ld",Nnurbs);
00075    NurbsTorus(MainNp,5.0,1.0);
00076  }
00077  else if(type == 3){
00078    NurbsTeapot();
00079  }
00080  EDIT_ACTION=YES;
00081  DrawModel();
00082  return;
00083 }
00084 
00085 void EditSelectedNurbsSurface(void){
00086  if(Nnurbs == 0 || MainNp == NULL)return;
00087  if(DialogBox(ghinst_main,MAKEINTRESOURCE(DLG_NURBSIKNOT),ghwnd_main,
00088                      (DLGPROC)NurbsIknotDlgProc)){
00089    EDIT_ACTION=YES;
00090    DrawModel();
00091  }
00092  return;
00093 }
00094 
00095 void SetSelectedNurbsWeights(void){
00096  if(Nnurbs == 0 || MainNp == NULL)return;
00097  DialogBox(ghinst_main,MAKEINTRESOURCE(DLG_NURBSWEIGHTS),ghwnd_main,
00098                      (DLGPROC)NurbsWeightsDlgProc);
00099  return;
00100 }
00101 
00102 static void NurbsTorus(nurbs *torus, double majorRadius, double minorRadius){
00103  /* These define the shape of a unit torus centered about the origin. */
00104  double xvalues[] = { 0.0, -1.0, -1.0, -1.0, 0.0, 1.0, 1.0, 1.0, 0.0 };
00105  double yvalues[] = { 1.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0, 1.0, 1.0 };
00106  double zvalues[] = { 0.0, 1.0, 1.0, 1.0, 0.0, -1.0, -1.0, -1.0, 0.0 };
00107  double offsets[] = { -1.0, -1.0, 0.0, 1.0, 1.0, 1.0, 0.0, -1.0, -1.0 };
00108  /* Piecewise Bezier knot vector for a quadratic curve with four segments */
00109  long knots[] = { 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4 };
00110 // long knots[] = { 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 7 }; // odd
00111  long i,j;
00112  double r2over2 = sqrt( 2.0 ) / 2.0;
00113  double weight;
00114  /* Set up the dimension and orders of the surface */
00115  torus->numU = 9;       /* A circle is formed from nine points */
00116  torus->numV = 9;
00117  torus->orderU = 3;       /* Quadratic in both directions */
00118  torus->orderV = 3;
00119  /* After the dimension and orders are set, AllocNurbs creates the dynamic
00120   * storage for the control points and the knot vectors */
00121  AllocNurbs(torus,NULL,NULL);
00122  for(i = 0; i < 9; i++){
00123    for(j = 0; j < 9; j++){
00124      weight = ((j & 1) ? r2over2 : 1.0) * ((i & 1) ? r2over2 : 1.0);
00125      /* Notice how the weights are pre-multiplied with the x, y and z values */
00126      torus->points[i][j].x = (NpointerX + xvalues[j] * (double)MINUNIT
00127                 * (majorRadius + offsets[i] * minorRadius)) * weight;
00128      torus->points[i][j].y = (NpointerY + yvalues[j] * (double)MINUNIT
00129                 * (majorRadius + offsets[i] * minorRadius)) * weight;
00130      torus->points[i][j].z = (NpointerZ + zvalues[i] * (double)MINUNIT
00131                 * (minorRadius)) * weight;
00132      torus->points[i][j].w = weight;
00133      torus->points[i][j].selected = FALSE;
00134    }
00135  }
00136  /* The knot vectors define piecewise Bezier segments (the same in both U and V). */
00137  for (i = 0; i < torus->numU + torus->orderU; i++){
00138    torus->kvU[i] = torus->kvV[i] = (double) knots[i];
00139  }
00140  return;
00141 }
00142 
00143 static void NurbsBezier(nurbs *torus, double width, double length){
00144  /* These define the shape of a flat Bezier patch. */
00145  double xvalues[] = { 0.0, 0.33333, 0.66666, 1.0};
00146  double yvalues[] = { 0.0, 0.33333, 0.66666, 1.0};
00147  double zvalues[] = { 0.0, 0.0,     0.0,     0.0};
00148  long knots[] = { 0, 0, 0, 0, 1, 1, 1, 1};
00149  long i,j;
00150  double weight=1.0;
00151  /* Set up the dimension and orders of the surface */
00152  torus->numU = 4;
00153  torus->numV = 4;
00154  torus->orderU = 4;    /* cubic in both directions */
00155  torus->orderV = 4;
00156  AllocNurbs(torus,NULL,NULL);
00157  for(i = 0; i < 4; i++){
00158    for(j = 0; j < 4; j++){
00159      /* Notice how the weights are pre-multiplied with the x, y and z values */
00160      torus->points[i][j].x = NpointerX + (xvalues[j] * (double)MINUNIT)
00161                 * width * weight;
00162      torus->points[i][j].y = NpointerY + (yvalues[i] * (double)MINUNIT)
00163                 * length * weight;
00164      torus->points[i][j].z = (NpointerZ)*weight;
00165      torus->points[i][j].w = weight;
00166      torus->points[i][j].selected = FALSE;
00167    }
00168  }
00169  /* The knot vectors define piecewise Bezier segments (the same in both U and V). */
00170  for (i = 0; i < torus->numU + torus->orderU; i++){
00171    torus->kvU[i] = torus->kvV[i] = (double) knots[i];
00172  }
00173  return;
00174 }
00175 
00176 static BOOL CheckHitNurbsOutline(int view, int x, int y,
00177                                  NurbsSurfSample *p1,
00178                                  NurbsSurfSample *p2){
00179  int sh1,sv1,sh2,sv2;
00180  vertex v,*vp;
00181  vp = &v;
00182  vp->status=SELECTED;
00183  vp->xyz[0]=(long)(p1->point[0]);
00184  vp->xyz[1]=(long)(p1->point[1]);
00185  vp->xyz[2]=(long)(p1->point[2]);
00186  if(intriview(vp)){
00187    GetWindowCoords(view,vp->xyz[0],vp->xyz[1],vp->xyz[2],&sh1,&sv1);
00188    vp->xyz[0]=(long)(p2->point[0]);
00189    vp->xyz[1]=(long)(p2->point[1]);
00190    vp->xyz[2]=(long)(p2->point[2]);
00191    if(intriview(vp)){
00192      GetWindowCoords(view,vp->xyz[0],vp->xyz[1],vp->xyz[2],&sh2,&sv2);
00193      if(labs(sh1-x) < 6 && labs(sv1-y) < 6)return TRUE;
00194      if(labs(sh2-x) < 6 && labs(sv2-y) < 6)return TRUE;
00195    }
00196  }
00197  return FALSE;
00198 }
00199 
00200 
00201 void SelectAllNurbs(BOOL state){
00202  nurbs *n;
00203  if(Nnurbs == 0 || MainNp == NULL)return;
00204  n=MainNp; while(n != NULL){
00205    n->selected=state;
00206    n=n->last;
00207  }
00208  DrawModel();
00209 }
00210 
00211 void SwapNurbsSelection(void){
00212  nurbs *n;
00213  if(Nnurbs == 0 || MainNp == NULL)return;
00214  n=MainNp; while(n != NULL){
00215    n->selected ^= 1;
00216    n=n->last;
00217  }
00218  DrawModel();
00219 }
00220 
00221 BOOL SelectNurbsPatch(int view, int x, int y){
00222  BOOL bHit;
00223  register long i,j;
00224  NurbsSurfSample **pts;
00225  long GranularityU,GranularityV;
00226  nurbs *n;
00227  if(Nnurbs == 0 || MainNp == NULL)return FALSE;
00228  bHit=FALSE;
00229  n=MainNp; while(n != NULL){
00230    if(!n->properties.hidden){
00231      GranularityU=n->properties.GranularityMax;
00232      GranularityV=n->properties.GranularityMin;
00233      if((pts=CreateSurfaceNet(n,GranularityU,GranularityV)) == NULL)return FALSE;
00234      for(i = 0; i < GranularityV; i++)
00235      for(j = 0; j < GranularityU; j++){
00236        if(bHit=CheckHitNurbsOutline(view,x,y,&pts[i][j],&pts[i][j+1]))goto XXIT1;
00237      }
00238      XXIT1:
00239 
00240      X__Free(pts[0]);
00241      X__Free(pts);
00242      if(!bHit){
00243        GranularityU=n->properties.GranularityMin;
00244        GranularityV=n->properties.GranularityMax;
00245        if((pts=CreateSurfaceNet(n,GranularityU,GranularityV)) == NULL)return FALSE;
00246        for(j = 0; j < GranularityU; j++)
00247        for(i = 0; i < GranularityV; i++){
00248          if(bHit=CheckHitNurbsOutline(view,x,y,&pts[i][j],&pts[i+1][j]))goto XXIT2;
00249        }
00250        XXIT2:
00251        X__Free(pts[0]);
00252        X__Free(pts);
00253      }
00254      if(bHit){
00255        n->selected ^= 1;
00256        if(!(n->selected)){
00257          for(i=0;i<n->numV;i++)
00258          for(j=0;j<n->numU;j++)(n->points[i][j]).selected=FALSE;
00259        }
00260        if(!(GetAsyncKeyState(VK_SHIFT) & 0x8000)){
00261          nurbs *np;
00262          np=MainNp; while(np != NULL){
00263            if(np != n){
00264              np->selected=FALSE;
00265            }
00266            np=np->last;
00267          }
00268        }
00269        DrawModel();
00270        return TRUE;
00271      }
00272    }
00273    n=n->last;
00274  }
00275  return FALSE;
00276 }
00277 
00278 vector4 *LastSelectedControlPoint=NULL;
00279 
00280 BOOL SelectNurbsControlPoint(int view, int x, int y){
00281  nurbs *np;
00282  int sh1,sv1;
00283  double w,d,dmin;
00284  vertex v,*vp;
00285  long i,j;
00286  vector4 *p1,*ps;
00287  LastSelectedControlPoint=NULL;
00288  if(Nnurbs == 0 || MainNp == NULL)return FALSE;
00289  dmin=(double)TVsizeY*(double)TVsizeY*(double)TVsizeZ;
00290  ps=NULL;
00291  vp=&v;
00292  vp->status=SELECTED;
00293  np=MainNp; while(np != NULL){
00294    if(np->selected){
00295      for(i=0;i<np->numV;i++)
00296      for(j=0;j<np->numU;j++){
00297        p1 = &(np->points[i][j]);
00298        w=1.0/p1->w;
00299        v.xyz[0]=(long)((p1->x)*w);
00300        v.xyz[1]=(long)((p1->y)*w);
00301        v.xyz[2]=(long)((p1->z)*w);
00302        if(intriview(vp)){
00303          GetWindowCoords(view,vp->xyz[0],vp->xyz[1],vp->xyz[2],
00304                          &sh1,&sv1);
00305          if(labs(sh1-x) < 4 && labs(sv1-y) < 4){
00306            d=(double)(vp->xyz[0]-NpointerX)*(double)(vp->xyz[0]-NpointerX)
00307             +(double)(vp->xyz[1]-NpointerY)*(double)(vp->xyz[1]-NpointerY)
00308             +(double)(vp->xyz[2]-NpointerZ)*(double)(vp->xyz[2]-NpointerZ);
00309             if(d < dmin){
00310               dmin=d;
00311               ps=p1;
00312             }
00313          }
00314        }
00315      }
00316    }
00317    np=np->last;
00318  }
00319  if(ps != NULL){
00320    if(ps->selected)LastSelectedControlPoint=ps;
00321    ps->selected = TRUE;
00322    return TRUE;
00323  }
00324  return FALSE;
00325 }
00326 
00327 static BOOL CheckNurbsIn(int view, int type,
00328                          long xl, long xr, long yt, long yb,
00329                          int cx, int cy, double radius1,
00330                          HRGN hrgn,
00331                          NurbsSurfSample *p1,
00332                          NurbsSurfSample *p2){
00333  int sh1,sv1,sh2,sv2;
00334  double radius2;
00335  vertex v,*vp;
00336  vp = &v;
00337  vp->status=SELECTED;
00338  vp->xyz[0]=(long)(p1->point[0]);
00339  vp->xyz[1]=(long)(p1->point[1]);
00340  vp->xyz[2]=(long)(p1->point[2]);
00341  if(intriview(vp)){
00342    GetWindowCoords(view,vp->xyz[0],vp->xyz[1],vp->xyz[2],&sh1,&sv1);
00343    vp->xyz[0]=(long)(p2->point[0]);
00344    vp->xyz[1]=(long)(p2->point[1]);
00345    vp->xyz[2]=(long)(p2->point[2]);
00346    if(intriview(vp)){
00347      GetWindowCoords(view,vp->xyz[0],vp->xyz[1],vp->xyz[2],&sh2,&sv2);
00348      if(type == 0){
00349        if(sh1 > xl && sh1 < xr && sv1 > yt && sv1 < yb &&
00350           sh2 > xl && sh2 < xr && sv2 > yt && sv2 < yb)return TRUE;
00351      }
00352      else if(type == 1){
00353        radius2 = (sqrt((double)(sh1-cx)*(double)(sh1-cx)
00354                       +(double)(sv1-cy)*(double)(sv1-cy)));
00355        if(radius2 < radius1){
00356          radius2 = (sqrt((double)(sh2-cx)*(double)(sh2-cx)
00357                         +(double)(sv2-cy)*(double)(sv2-cy)));
00358          if(radius2 < radius1)return TRUE;
00359        }
00360      }
00361      else if(type == 2){
00362        if(PtInRegion(hrgn,sh1,sv1) && PtInRegion(hrgn,sh2,sv2))return TRUE;
00363      }
00364    }
00365  }
00366  return FALSE;
00367 }
00368 
00369 void SelectNurbsInRectangle(int Tool, BOOL bFlagNodeTool,
00370                             long xl, long xr, long yt, long yb){
00371  long i,j;
00372  nurbs *np;
00373  int sx,sy;
00374  double w;
00375  vertex v,*vp;
00376  vector4 *p1;
00377  if(Nnurbs == 0 || MainNp == NULL)return;
00378  vp=&v;
00379  vp->status=SELECTED;
00380  if(bFlagNodeTool){
00381    np=MainNp; while(np != NULL){
00382      if(np->selected){
00383        for(i=0;i<np->numV;i++)
00384        for(j=0;j<np->numU;j++){
00385          p1 = &(np->points[i][j]);
00386          w=1.0/p1->w;
00387          v.xyz[0]=(long)((p1->x)*w);
00388          v.xyz[1]=(long)((p1->y)*w);
00389          v.xyz[2]=(long)((p1->z)*w);
00390          if(intriview(vp)){
00391            GetWindowCoords(ActiveView,vp->xyz[0],vp->xyz[1],vp->xyz[2],
00392                            &sx,&sy);
00393            if((sx > xl) && (sx < xr) && (sy > yt) && (sy < yb)){
00394              if(Tool == SELECTOR)p1->selected=TRUE;
00395              else                p1->selected=FALSE;
00396            }
00397          }
00398        }
00399      }
00400      np=np->last;
00401    }
00402  }
00403  else{
00404    long bHit;
00405    NurbsSurfSample **pts;
00406    long GranularityU,GranularityV;
00407    np=MainNp; while(np != NULL){
00408      bHit=0;
00409      GranularityU=np->properties.GranularityMax;
00410      GranularityV=np->properties.GranularityMin;
00411      if((pts=CreateSurfaceNet(np,GranularityU,GranularityV)) == NULL)return;
00412      for(i = 0; i < GranularityV; i++)
00413      for(j = 0; j < GranularityU; j++){
00414        if(CheckNurbsIn(ActiveView,0,
00415                        xl,xr,yt,yb,
00416                        0,0,0.0,
00417                        (HRGN)NULL,
00418                        &pts[i][j],&pts[i][j+1])){
00419          if(bHit == 0)bHit=1;
00420        }
00421        else bHit = -1;
00422      }
00423      X__Free(pts[0]);
00424      X__Free(pts);
00425      GranularityU=np->properties.GranularityMin;
00426      GranularityV=np->properties.GranularityMax;
00427      if((pts=CreateSurfaceNet(np,GranularityU,GranularityV)) == NULL)return;
00428      for(j = 0; j < GranularityU; j++)
00429      for(i = 0; i < GranularityV; i++){
00430        if(CheckNurbsIn(ActiveView,0,
00431                        xl,xr,yt,yb,
00432                        0,0,0.0,
00433                        (HRGN)NULL,
00434                        &pts[i][j],&pts[i+1][j])){
00435 
00436          if(bHit == 0)bHit=1;
00437        }
00438        else bHit = -1;
00439      }
00440      X__Free(pts[0]);
00441      X__Free(pts);
00442      if(bHit == 1){
00443        if(Tool == SELECTOR)np->selected=TRUE;
00444        else                np->selected=FALSE;
00445      }
00446      np=np->last;
00447    }
00448  }
00449  return;
00450 }
00451 
00452 void SelectNurbsInCircle(int Tool, BOOL bFlagNodeTool,
00453                          int cx, int cy, double radius1){
00454  long i,j;
00455  nurbs *np;
00456  int sx,sy;
00457  double w,radius2;
00458  vertex v,*vp;
00459  vector4 *p1;
00460  if(Nnurbs == 0 || MainNp == NULL)return;
00461  vp=&v;
00462  vp->status=SELECTED;
00463  if(bFlagNodeTool){
00464    np=MainNp; while(np != NULL){
00465      if(np->selected){
00466        for(i=0;i<np->numV;i++)
00467        for(j=0;j<np->numU;j++){
00468          p1 = &(np->points[i][j]);
00469          w=1.0/p1->w;
00470          v.xyz[0]=(long)((p1->x)*w);
00471          v.xyz[1]=(long)((p1->y)*w);
00472          v.xyz[2]=(long)((p1->z)*w);
00473          if(intriview(vp)){
00474            GetWindowCoords(ActiveView,vp->xyz[0],vp->xyz[1],vp->xyz[2],
00475                            &sx,&sy);
00476            radius2 = (sqrt((double)(sx-cx)*(double)(sx-cx)
00477                           +(double)(sy-cy)*(double)(sy-cy)));
00478            if(radius2 < radius1){
00479              if(Tool == SELECTOR)p1->selected=TRUE;
00480              else                p1->selected=FALSE;
00481            }
00482          }
00483        }
00484      }
00485      np=np->last;
00486    }
00487  }
00488  else{
00489    long bHit;
00490    NurbsSurfSample **pts;
00491    long GranularityU,GranularityV;
00492    np=MainNp; while(np != NULL){
00493      bHit=0;
00494      GranularityU=np->properties.GranularityMax;
00495      GranularityV=np->properties.GranularityMin;
00496      if((pts=CreateSurfaceNet(np,GranularityU,GranularityV)) == NULL)return;
00497      for(i = 0; i < GranularityV; i++)
00498      for(j = 0; j < GranularityU; j++){
00499        if(CheckNurbsIn(ActiveView,1,
00500                        0,0,0,0,
00501                        cx,cy,radius1,
00502                        (HRGN)NULL,
00503                        &pts[i][j],&pts[i][j+1])){
00504          if(bHit == 0)bHit=1;
00505        }
00506        else bHit = -1;
00507      }
00508      X__Free(pts[0]);
00509      X__Free(pts);
00510      GranularityU=np->properties.GranularityMin;
00511      GranularityV=np->properties.GranularityMax;
00512      if((pts=CreateSurfaceNet(np,GranularityU,GranularityV)) == NULL)return;
00513      for(j = 0; j < GranularityU; j++)
00514      for(i = 0; i < GranularityV; i++){
00515        if(CheckNurbsIn(ActiveView,1,
00516                        0,0,0,0,
00517                        cx,cy,radius1,
00518                        (HRGN)NULL,
00519                        &pts[i][j],&pts[i+1][j])){
00520 
00521          if(bHit == 0)bHit=1;
00522        }
00523        else bHit = -1;
00524      }
00525      X__Free(pts[0]);
00526      X__Free(pts);
00527      if(bHit == 1){
00528        if(Tool == SELECTOR)np->selected=TRUE;
00529        else                np->selected=FALSE;
00530      }
00531      np=np->last;
00532    }
00533  }
00534  return;
00535 }
00536 
00537 void SelectNurbsInLasso(int Tool, BOOL bFlagNodeTool, HRGN hrgn){
00538  long i,j;
00539  nurbs *np;
00540  int sx,sy;
00541  double w;
00542  vertex v,*vp;
00543  vector4 *p1;
00544  if(Nnurbs == 0 || MainNp == NULL)return;
00545  vp=&v;
00546  vp->status=SELECTED;
00547  if(bFlagNodeTool){
00548    np=MainNp; while(np != NULL){
00549      if(np->selected){
00550        for(i=0;i<np->numV;i++)
00551        for(j=0;j<np->numU;j++){
00552          p1 = &(np->points[i][j]);
00553          w=1.0/p1->w;
00554          v.xyz[0]=(long)((p1->x)*w);
00555          v.xyz[1]=(long)((p1->y)*w);
00556          v.xyz[2]=(long)((p1->z)*w);
00557          if(intriview(vp)){
00558            GetWindowCoords(ActiveView,vp->xyz[0],vp->xyz[1],vp->xyz[2],
00559                            &sx,&sy);
00560            if(PtInRegion(hrgn,sx,sy)){
00561              if(Tool == SELECTOR)p1->selected=TRUE;
00562              else                p1->selected=FALSE;
00563            }
00564          }
00565        }
00566      }
00567      np=np->last;
00568    }
00569  }
00570  else{
00571    long bHit;
00572    NurbsSurfSample **pts;
00573    long GranularityU,GranularityV;
00574    np=MainNp; while(np != NULL){
00575      bHit=0;
00576      GranularityU=np->properties.GranularityMax;
00577      GranularityV=np->properties.GranularityMin;
00578      if((pts=CreateSurfaceNet(np,GranularityU,GranularityV)) == NULL)return;
00579      for(i = 0; i < GranularityV; i++)
00580      for(j = 0; j < GranularityU; j++){
00581        if(CheckNurbsIn(ActiveView,2,
00582                        0,0,0,0,
00583                        0,0,0.0,
00584                        hrgn,
00585                        &pts[i][j],&pts[i][j+1])){
00586          if(bHit == 0)bHit=1;
00587        }
00588        else bHit = -1;
00589      }
00590      X__Free(pts[0]);
00591      X__Free(pts);
00592      GranularityU=np->properties.GranularityMin;
00593      GranularityV=np->properties.GranularityMax;
00594      if((pts=CreateSurfaceNet(np,GranularityU,GranularityV)) == NULL)return;
00595      for(j = 0; j < GranularityU; j++)
00596      for(i = 0; i < GranularityV; i++){
00597        if(CheckNurbsIn(ActiveView,2,
00598                        0,0,0,0,
00599                        0,0,0.0,
00600                        hrgn,
00601                        &pts[i][j],&pts[i+1][j])){
00602 
00603          if(bHit == 0)bHit=1;
00604        }
00605        else bHit = -1;
00606      }
00607      X__Free(pts[0]);
00608      X__Free(pts);
00609      if(bHit == 1){
00610        if(Tool == SELECTOR)np->selected=TRUE;
00611        else                np->selected=FALSE;
00612      }
00613      np=np->last;
00614    }
00615  }
00616  return;
00617 }
00618 
00619 void HideNurbs(BOOL hide){
00620  nurbs *np;
00621  if(Nnurbs == 0 || MainNp == NULL)return;
00622  np=MainNp; while(np != NULL){
00623    if(hide){
00624      if(np->selected){
00625        np->properties.hidden=1;
00626        np->selected=FALSE;
00627      }
00628    }
00629    else{
00630      np->properties.hidden=0;
00631    }
00632    np=np->last;
00633  }
00634  DrawModel();
00635  return;
00636 }
00637 
00638 void MoveNurbsControlPoint(int view, int x, int y, int UpOrDown){
00639  static long last_x,last_y,last_z;
00640  nurbs *np;
00641  double w,xp,yp,zp;
00642  long i,j;
00643  vector4 *p1;
00644  long dx,dy,dz;
00645  if(Nnurbs == 0 || MainNp == NULL)return;
00646  if(UpOrDown > 0){ // Down
00647    np=MainNp; while(np != NULL){
00648      if(np->selected)DrawInvertNurbsInOne(np,view,TRUE);
00649      np=np->last;
00650    }
00651  }
00652  else if(UpOrDown == 0){ // Move
00653    dx=NpointerX-last_x;
00654    dy=NpointerY-last_y;
00655    dz=NpointerZ-last_z;
00656    np=MainNp; while(np != NULL){
00657      if(np->selected){
00658        DrawInvertNurbsInOne(np,view,FALSE);
00659        for(i=0;i<np->numV;i++)
00660        for(j=0;j<np->numU;j++){
00661          p1 = &(np->points[i][j]);
00662          if(p1->selected){
00663            w=1.0/p1->w;
00664            xp=((p1->x)*w);
00665            yp=((p1->y)*w);
00666            zp=((p1->z)*w);
00667            xp += (double)dx;
00668            yp += (double)dy;
00669            zp += (double)dz;
00670            w=p1->w;
00671            p1->x = xp*w;
00672            p1->y = yp*w;
00673            p1->z = zp*w;
00674          }
00675        }
00676        DrawInvertNurbsInOne(np,view,TRUE);
00677      }
00678      np=np->last;
00679    }
00680    LastSelectedControlPoint=NULL;
00681  }
00682  else if(UpOrDown < 0){ // Up
00683    if(!(GetAsyncKeyState(VK_CONTROL) & 0x8000)){
00684      np=MainNp; while(np != NULL){
00685        if(np->selected){
00686          for(i=0;i<np->numV;i++)
00687          for(j=0;j<np->numU;j++){
00688            p1 = &(np->points[i][j]);
00689            if(p1->selected){
00690              p1->selected=FALSE;
00691            }
00692          }
00693        }
00694        np=np->last;
00695      }
00696    }
00697    else if(LastSelectedControlPoint != NULL){
00698      LastSelectedControlPoint->selected=FALSE;
00699    }
00700  }
00701  last_x=NpointerX; last_y=NpointerY; last_z=NpointerZ;
00702 }
00703 
00704 void MoveNurbsSurface(int view, int x, int y, int UpOrDown){
00705  static long last_x,last_y,last_z;
00706  nurbs *np;
00707  double w,xp,yp,zp;
00708  long i,j;
00709  vector4 *p1;
00710  long dx,dy,dz;
00711  if(Nnurbs == 0 || MainNp == NULL)return;
00712  if(UpOrDown > 0){ // Down
00713    np=MainNp; while(np != NULL){
00714      if(np->selected)DrawInvertNurbsInOne(np,view,TRUE);
00715      np=np->last;
00716    }
00717  }
00718  else if(UpOrDown == 0){ // Move
00719    dx=NpointerX-last_x;
00720    dy=NpointerY-last_y;
00721    dz=NpointerZ-last_z;
00722    np=MainNp; while(np != NULL){
00723      if(np->selected){
00724        DrawInvertNurbsInOne(np,view,FALSE);
00725        for(i=0;i<np->numV;i++)
00726        for(j=0;j<np->numU;j++){
00727          p1 = &(np->points[i][j]);
00728          w=1.0/p1->w;
00729          xp=((p1->x)*w);
00730          yp=((p1->y)*w);
00731          zp=((p1->z)*w);
00732          xp += (double)dx;
00733          yp += (double)dy;
00734          zp += (double)dz;
00735          w=p1->w;
00736          p1->x = xp*w;
00737          p1->y = yp*w;
00738          p1->z = zp*w;
00739        }
00740        DrawInvertNurbsInOne(np,view,TRUE);
00741      }
00742      np=np->last;
00743    }
00744  }
00745  else if(UpOrDown < 0){ // Up
00746  }
00747  last_x=NpointerX; last_y=NpointerY; last_z=NpointerZ;
00748  return;
00749 }
00750 
00751 void XpandNurbsSurface(int view, int UpOrDown, double sx, double sy, double sz){
00752  static long last_x,last_y,last_z;
00753  nurbs *np;
00754  double w,xp,yp,zp;
00755  long i,j;
00756  vector4 *p1;
00757  if(Nnurbs == 0 || MainNp == NULL)return;
00758  if(UpOrDown != 0){ // Down or Up
00759    np=MainNp; while(np != NULL){
00760      if(np->selected)DrawInvertNurbsInOne(np,view,TRUE);
00761      np=np->last;
00762    }
00763    last_x=NpointerX; last_y=NpointerY; last_z=NpointerZ;
00764  }
00765  else if(UpOrDown == 0){ // Move
00766    np=MainNp; while(np != NULL){
00767      if(np->selected){
00768        DrawInvertNurbsInOne(np,view,FALSE);
00769        for(i=0;i<np->numV;i++)
00770        for(j=0;j<np->numU;j++){
00771          p1 = &(np->points[i][j]);
00772          w=1.0/p1->w;
00773          xp=((p1->x)*w);
00774          yp=((p1->y)*w);
00775          zp=((p1->z)*w);
00776          xp = (xp-(double)last_x)*sx+(double)last_x;
00777          yp = (yp-(double)last_y)*sy+(double)last_y;
00778          zp = (zp-(double)last_z)*sz+(double)last_z;
00779          w=p1->w;
00780          p1->x = xp*w;
00781          p1->y = yp*w;
00782          p1->z = zp*w;
00783        }
00784        DrawInvertNurbsInOne(np,view,TRUE);
00785      }
00786      np=np->last;
00787    }
00788  }
00789  return;
00790 }
00791 
00792 static void RotateNurbsPoint(double x, double y, long X, long Y,
00793                              double *tx, double *ty,
00794                              double ctheta, double stheta){
00795  double dx,dy;
00796  dx=(x-(double)X);
00797  dy=(y-(double)Y);
00798  *tx = (double)X+(ctheta*dx-stheta*dy);
00799  *ty = (double)Y+(stheta*dx+ctheta*dy);
00800 }
00801 
00802 void RotateNurbsSurface(int view, int UpOrDown, double RotatorTheta){
00803  static long GrabonX,GrabonY,GrabonZ;
00804  static long lastRotator;
00805  nurbs *np;
00806  double xp,yp,x,y,z;
00807  double w,ctheta,stheta,beta;
00808  long i,j;
00809  vector4 *p1;
00810  if(Nnurbs == 0 || MainNp == NULL)return;
00811  if(UpOrDown != 0){ // Down or Up
00812    np=MainNp; while(np != NULL){
00813      if(np->selected)DrawInvertNurbsInOne(np,view,TRUE);
00814      np=np->last;
00815    }
00816    GrabonX=NpointerX; GrabonY=NpointerY; GrabonZ=NpointerZ;
00817    lastRotator=0.0;
00818  }
00819  else if(UpOrDown == 0){ // Move
00820 //   beta=RotatorTheta-lastRotator;
00821    beta=RotatorTheta;
00822    lastRotator=RotatorTheta;
00823    ctheta=cos(beta); stheta=sin(beta);
00824    np=MainNp; while(np != NULL){
00825      if(np->selected){
00826        DrawInvertNurbsInOne(np,view,FALSE);
00827        for(i=0;i<np->numV;i++)
00828        for(j=0;j<np->numU;j++){
00829          p1 = &(np->points[i][j]);
00830          w=1.0/p1->w;
00831          x=((p1->x)*w);
00832          y=((p1->y)*w);
00833          z=((p1->z)*w);
00834          if(view == TRITOP){
00835            RotateNurbsPoint(x,y,GrabonX,GrabonY,&xp,&yp,ctheta,stheta);
00836            x=xp; y=yp;
00837          }
00838          else if(view == TRIFRONT){
00839            RotateNurbsPoint(x,z,GrabonX,GrabonZ,&xp,&yp,ctheta,stheta);
00840            x=xp; z=yp;
00841          }
00842          else if(view == TRIRIGHT){
00843            RotateNurbsPoint(y,z,GrabonY,GrabonZ,&xp,&yp,ctheta,stheta);
00844            y=xp; z=yp;
00845          }
00846          w=p1->w;
00847          p1->x = x*w;
00848          p1->y = y*w;
00849          p1->z = z*w;
00850        }
00851        DrawInvertNurbsInOne(np,view,TRUE);
00852      }
00853      np=np->last;
00854    }
00855  }
00856  return;
00857 }
00858 
00859 void RotateNurbsAction(int axis, double theta){
00860  nurbs *np;
00861  double x,y,z;
00862  double w,ctheta,stheta,beta;
00863  long i,j;
00864  vector4 *p1;
00865  if(Nnurbs == 0 || MainNp == NULL)return;
00866  ctheta=cos(theta); stheta=sin(theta);
00867  np=MainNp; while(np != NULL){
00868    if(np->selected){
00869      for(i=0;i<np->numV;i++)
00870      for(j=0;j<np->numU;j++){
00871        p1 = &(np->points[i][j]);
00872        w=1.0/p1->w;
00873        x=((p1->x)*w);
00874        y=((p1->y)*w);
00875        z=((p1->z)*w);
00876        if(axis == 0){
00877          RotateNurbsPoint(x,y,NpointerX,NpointerY,&x,&y,ctheta,stheta);
00878        }
00879        else if(axis == 1){
00880          RotateNurbsPoint(x,z,NpointerX,NpointerZ,&x,&z,ctheta,stheta);
00881        }
00882        else if(axis == 2){
00883          RotateNurbsPoint(y,z,NpointerY,NpointerZ,&y,&z,ctheta,stheta);
00884        }
00885        w=p1->w;
00886        p1->x = x*w;
00887        p1->y = y*w;
00888        p1->z = z*w;
00889      }
00890    }
00891    np=np->last;
00892  }
00893  return;
00894 }
00895 
00896 void ExpandNurbsAction(long cx, long cy, long cz,
00897                        double sx, double sy, double sz){
00898  nurbs *np;
00899  double w,xp,yp,zp;
00900  long i,j;
00901  vector4 *p1;
00902  if(Nnurbs == 0 || MainNp == NULL)return;
00903  np=MainNp; while(np != NULL){
00904    if(np->selected){
00905      for(i=0;i<np->numV;i++)
00906      for(j=0;j<np->numU;j++){
00907        p1 = &(np->points[i][j]);
00908        w=1.0/p1->w;
00909        xp=((p1->x)*w);
00910        yp=((p1->y)*w);
00911        zp=((p1->z)*w);
00912        xp = (xp-(double)cx)*sx+(double)cx;
00913        yp = (yp-(double)cy)*sy+(double)cy;
00914        zp = (zp-(double)cz)*sz+(double)cz;
00915        w=p1->w;
00916        p1->x = xp*w;
00917        p1->y = yp*w;
00918        p1->z = zp*w;
00919      }
00920    }
00921    np=np->last;
00922  }
00923  return;
00924 }
00925 
00926 void DuplicateSelectedNurbs(void){
00927  nurbs *np;
00928  if(Nnurbs == 0 || MainNp == NULL)return;
00929  np=MainNp; while(np != NULL){
00930    if(np->selected){
00931      EDIT_ACTION=YES;
00932      CreateNurbs();
00933      CloneNurbs(np,MainNp);
00934      MainNp->selected=FALSE;
00935    }
00936    np=np->last;
00937  }
00938  return;
00939 }
00940 
00941 void SplitNurbs(void){
00942  if(Nnurbs == 0 || MainNp == NULL)return;
00943  if(DialogBox(ghinst_main,MAKEINTRESOURCE(DLG_NURBSSPLIT),ghwnd_main,
00944                      (DLGPROC)NurbsSplitDlgProc)){
00945    EDIT_ACTION=YES;
00946    DrawModel();
00947  }
00948  return;
00949 }
00950 
00951 #include "nurbs0.c"
00952 #include "nurbs1.c"
00953 #include "nurbs2.c"
00954 #include "teapot.c"
00955 

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