NURBS0.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 NURBS0.C */
00025 
00026 void IncludeNurbsBoundary(short *flag,
00027                           long *xmin, long *xmax,
00028                           long *ymin, long *ymax,
00029                           long *zmin, long *zmax){
00030  nurbs *np;
00031  long i,j,x,y,z;
00032  double w;
00033  vector4 *p1;
00034  if(Nnurbs == 0 || MainNp == NULL)return;
00035  *flag = 1;
00036  np=MainNp; while(np != NULL){
00037    for(i=0;i<np->numV;i++)
00038    for(j=0;j<np->numU;j++){
00039      p1 = &(np->points[i][j]);
00040      w=1.0/p1->w;
00041      x=(long)((p1->x)*w);
00042      y=(long)((p1->y)*w);
00043      z=(long)((p1->z)*w);
00044      if(x < *xmin)*xmin=x; if(y < *ymin)*ymin=y; if(z < *zmin)*zmin=z;
00045      if(x > *xmax)*xmax=x; if(y > *ymax)*ymax=y; if(z > *zmax)*zmax=z;
00046    }
00047    np=np->last;
00048  }
00049  return;
00050 }
00051 
00052 static void DrawNurbsEdge(HDC hdc, int view,
00053                           NurbsSurfSample *p1, NurbsSurfSample *p2){
00054  int sh1,sv1,sh2,sv2;
00055  vertex v,*vp;
00056  vp = &v;
00057  vp->status=SELECTED;
00058  vp->xyz[0]=(long)(p1->point[0]);
00059  vp->xyz[1]=(long)(p1->point[1]);
00060  vp->xyz[2]=(long)(p1->point[2]);
00061  if(intriview(vp)){
00062    GetWindowCoords(view,vp->xyz[0],vp->xyz[1],vp->xyz[2],&sh1,&sv1);
00063    vp->xyz[0]=(long)(p2->point[0]);
00064    vp->xyz[1]=(long)(p2->point[1]);
00065    vp->xyz[2]=(long)(p2->point[2]);
00066    if(intriview(vp)){
00067      GetWindowCoords(view,vp->xyz[0],vp->xyz[1],vp->xyz[2],&sh2,&sv2);
00068      MoveToEx(hdc,sh1,sv1,NULL); LineTo(hdc,sh2,sv2);
00069    }
00070  }
00071  return;
00072 }
00073 
00074 static BOOL DrawNurbsOutline(HDC hdc, int view, nurbs *n, BOOL abort){
00075  BOOL bAbort=FALSE;
00076  register long i,j;
00077  NurbsSurfSample **pts;
00078  long GranularityU,GranularityV;
00079  GranularityU=n->properties.GranularityMax;
00080  GranularityV=n->properties.GranularityMin;
00081  if((pts=CreateSurfaceNet(n,GranularityU,GranularityV)) == NULL)return FALSE;
00082  for(i = 0; i < GranularityV+1; i++)
00083  for(j = 0; j < GranularityU; j++){
00084    DrawNurbsEdge(hdc,view,&pts[i][j],&pts[i][j+1]);
00085    if(abort && HIWORD(GetQueueStatus(QS_MOUSEMOVE)) == QS_MOUSEMOVE){
00086      bAbort=TRUE;
00087      goto ABORT1;
00088    }
00089  }
00090  ABORT1:
00091  X__Free(pts[0]);
00092  X__Free(pts);
00093  if(bAbort)return TRUE;
00094  GranularityU=n->properties.GranularityMin;
00095  GranularityV=n->properties.GranularityMax;
00096  if((pts=CreateSurfaceNet(n,GranularityU,GranularityV)) == NULL)return FALSE;
00097  for(j = 0; j < GranularityU+1; j++)
00098  for(i = 0; i < GranularityV; i++){
00099    DrawNurbsEdge(hdc,view,&pts[i][j],&pts[i+1][j]);
00100    if(abort && HIWORD(GetQueueStatus(QS_MOUSEMOVE)) == QS_MOUSEMOVE){
00101      bAbort=TRUE;
00102      goto ABORT2;
00103    }
00104  }
00105  ABORT2:
00106  X__Free(pts[0]);
00107  X__Free(pts);
00108  if(bAbort)return TRUE;
00109  return FALSE;
00110 }
00111 
00112 static void DrawNurbsControlPoints(nurbs *np, HDC hdc, int view, BOOL status){
00113  HPEN hOldPen;
00114  int hOldMode;
00115  int sh1,sv1;
00116  double w;
00117  vertex v,*vp;
00118  long i,j,x,y,z;
00119  vector4 *p1;
00120  vp=&v;
00121  vp->status=SELECTED;
00122  hOldMode=SetBkMode(hdc,TRANSPARENT);
00123  if(status)hOldPen=SelectObject(hdc,ghDotSelectedPen);
00124  for(i=0;i<np->numV;i++)
00125  for(j=0;j<np->numU-1;j++){
00126    p1 = &(np->points[i][j]);
00127    w=1.0/p1->w;
00128    v.xyz[0]=(long)((p1->x)*w);
00129    v.xyz[1]=(long)((p1->y)*w);
00130    v.xyz[2]=(long)((p1->z)*w);
00131    if(intriview(vp)){
00132      GetWindowCoords(view,vp->xyz[0],vp->xyz[1],vp->xyz[2],&sh1,&sv1);
00133      MoveToEx(hdc,sh1,sv1,NULL);
00134      p1 = &(np->points[i][j+1]);
00135      w=1.0/p1->w;
00136      v.xyz[0]=(long)((p1->x)*w);
00137      v.xyz[1]=(long)((p1->y)*w);
00138      v.xyz[2]=(long)((p1->z)*w);
00139      GetWindowCoords(view,vp->xyz[0],vp->xyz[1],vp->xyz[2],&sh1,&sv1);
00140      LineTo(hdc,sh1,sv1);
00141    }
00142  }
00143  for(j=0;j<np->numU;j++)
00144  for(i=0;i<np->numV-1;i++){
00145    p1 = &(np->points[i][j]);
00146    w=1.0/p1->w;
00147    v.xyz[0]=(long)((p1->x)*w);
00148    v.xyz[1]=(long)((p1->y)*w);
00149    v.xyz[2]=(long)((p1->z)*w);
00150    if(intriview(vp)){
00151      GetWindowCoords(view,vp->xyz[0],vp->xyz[1],vp->xyz[2],&sh1,&sv1);
00152      MoveToEx(hdc,sh1,sv1,NULL);
00153      p1 = &(np->points[i+1][j]);
00154      w=1.0/p1->w;
00155      v.xyz[0]=(long)((p1->x)*w);
00156      v.xyz[1]=(long)((p1->y)*w);
00157      v.xyz[2]=(long)((p1->z)*w);
00158      GetWindowCoords(view,vp->xyz[0],vp->xyz[1],vp->xyz[2],&sh1,&sv1);
00159      LineTo(hdc,sh1,sv1);
00160    }
00161  }
00162  if(status)SelectObject(hdc,ghEdgePen);
00163  SetBkMode(hdc,hOldMode);
00164 
00165  for(i=0;i<np->numV;i++)
00166  for(j=0;j<np->numU;j++){
00167    p1 = &(np->points[i][j]);
00168    if(!(p1->selected)){
00169      w=1.0/p1->w;
00170      v.xyz[0]=(long)((p1->x)*w);
00171      v.xyz[1]=(long)((p1->y)*w);
00172      v.xyz[2]=(long)((p1->z)*w);
00173      if(intriview(vp)){
00174        GetWindowCoords(view,vp->xyz[0],vp->xyz[1],vp->xyz[2],&sh1,&sv1);
00175        Rectangle(hdc,sh1-1,sv1-1,sh1+2,sv1+2);
00176      }
00177    }
00178  }
00179  if(status)SelectObject(hdc,ghSelectedPen);
00180  for(i=0;i<np->numV;i++)
00181  for(j=0;j<np->numU;j++){
00182    p1 = &(np->points[i][j]);
00183    if(p1->selected){
00184      w=1.0/p1->w;
00185      v.xyz[0]=(long)((p1->x)*w);
00186      v.xyz[1]=(long)((p1->y)*w);
00187      v.xyz[2]=(long)((p1->z)*w);
00188      if(intriview(vp)){
00189        GetWindowCoords(view,vp->xyz[0],vp->xyz[1],vp->xyz[2],&sh1,&sv1);
00190        if(status && p1->selected)hOldPen=SelectObject(hdc,ghSelectedPen);
00191        Rectangle(hdc,sh1-1,sv1-1,sh1+2,sv1+2);
00192        if(status && p1->selected)SelectObject(hdc,hOldPen);
00193      }
00194    }
00195  }
00196  if(status)SelectObject(hdc,hOldPen);
00197  return;
00198 }
00199 
00200 void DrawAllNurbsInOne(HDC hdc, int view, BOOL abort){
00201  BOOL bAbort=FALSE;
00202  HPEN hOldPen;
00203  nurbs *np;
00204  if(Nnurbs == 0 || MainNp == NULL)return;
00205  np=MainNp; while(np != NULL){
00206    if(!np->selected && !np->properties.hidden){
00207      bAbort=DrawNurbsOutline(hdc,view,np,abort);
00208      if(bAbort)goto ABORT;
00209    }
00210    np=np->last;
00211  }
00212  np=MainNp; while(np != NULL){
00213    if(np->selected && !np->properties.hidden){
00214      hOldPen=SelectObject(hdc,ghSelectedPen);
00215      bAbort=DrawNurbsOutline(hdc,view,np,abort);
00216      SelectObject(hdc,hOldPen);
00217      if(bAbort)goto ABORT;
00218      DrawNurbsControlPoints(np,hdc,view,TRUE);
00219    }
00220    np=np->last;
00221  }
00222  ABORT:
00223  return;
00224 }
00225 
00226 static void DrawInvertNurbsInOne(nurbs *np, int view, BOOL update){
00227  HDC hdc;
00228  HPEN hOldPen;
00229  DWORD oldROP2;
00230  if(np->properties.hidden)return;
00231  if((hdc=ghdc_triview_Bitmap[view]) == NULL)return;
00232  hOldPen=SelectObject(hdc,ghInvertPen);
00233  oldROP2=SetROP2(hdc,R2_XORPEN);
00234  DrawNurbsControlPoints(np,hdc,view,FALSE);
00235  DrawNurbsOutline(hdc,view,np,FALSE);
00236  SelectObject(hdc,hOldPen);
00237  SetROP2(hdc,oldROP2);
00238  if(update){
00239    InvalidateRect(ghwnd_triview[view],NULL,FALSE);
00240    UpdateWindow(ghwnd_triview[view]);
00241  }
00242  return;
00243 }
00244 
00245 void DrawNurbsWireFrame(HDC hdc, int skelview,
00246                         double scale, double trr[4][4],
00247                         short (*in_modeller_view1)(vertex *, vertex *),
00248                         short (*in_modeller_view2)(vertex *, vertex *),
00249                         BOOL abort){
00250  BOOL bAbort=FALSE;
00251  double x1,y1,z1,x2,y2,z2;
00252  int ix1,ix2,iy1,iy2,flag,
00253      pwinl,pwinr,pwint,pwinb,pwincx,pwincy;
00254  short (*in_modeller_view)(vertex *vp1, vertex *vp2);
00255  RECT rc;
00256  int sh1,sv1;
00257  nurbs *n;
00258  long i,j;
00259  vertex V1,V2,*v1,*v2;
00260  if(Nnurbs == 0 || MainNp == NULL)return;
00261  if(!draw_joins)in_modeller_view = in_modeller_view2; /* scroll lock   */
00262  else           in_modeller_view = in_modeller_view1; /* test function */
00263  GetClientRect(ghwnd_view,&rc);
00264  pwinl=pwint=0; pwinr=rc.right; pwinb=rc.bottom;
00265  pwincx=rc.right/2; pwincy=rc.bottom/2;
00266  v1 = &V1; v2 = &V2;
00267  v1->status=SELECTED;
00268  v2->status=SELECTED;
00269  n=MainNp; while(n != NULL){
00270    if(!n->properties.hidden){
00271      NurbsSurfSample **pts;
00272      long GranularityU,GranularityV;
00273      GranularityU=n->properties.GranularityMax;
00274      GranularityV=n->properties.GranularityMin;
00275      if((pts=CreateSurfaceNet(n,GranularityU,GranularityV)) == NULL)return;
00276      for(i = 0; i < GranularityV+1; i++)
00277      for(j = 0; j < GranularityU; j++){
00278        v1->xyz[0]=(long)(pts[i][j].point[0]);
00279        v1->xyz[1]=(long)(pts[i][j].point[1]);
00280        v1->xyz[2]=(long)(pts[i][j].point[2]);
00281        v2->xyz[0]=(long)(pts[i][j+1].point[0]);
00282        v2->xyz[1]=(long)(pts[i][j+1].point[1]);
00283        v2->xyz[2]=(long)(pts[i][j+1].point[2]);
00284        if(in_modeller_view(v1,v2)){
00285          flag=0;
00286          m4by1(trr,(double)v1->xyz[0],(double)v1->xyz[1],(double)v1->xyz[2]
00287                   ,&x1,&y1,&z1);
00288          m4by1(trr,(double)v2->xyz[0],(double)v2->xyz[1],(double)v2->xyz[2]
00289                   ,&x2,&y2,&z2);
00290          if(y1 >= 0.0){
00291            ix1=(int)(pwincx+scale*x1);
00292            iy1=(int)(pwincy-scale*z1);
00293          }
00294          else  flag=1;
00295          if(y2 >= 0.0){
00296            ix2=(int)(pwincx+scale*x2);
00297            iy2=(int)(pwincy-scale*z2);
00298          }
00299          else flag=1;
00300          if(flag == 0){// && (!Preferences.quick_trick || abs(ix1-ix2) > 2 || abs(iy1-iy2) > 2) ){
00301            MoveToEx(hdc,ix1,iy1,NULL);
00302            LineTo(hdc,ix2,iy2);
00303          }
00304        }
00305        if(abort && HIWORD(GetQueueStatus(QS_MOUSEMOVE)) == QS_MOUSEMOVE){
00306          bAbort=TRUE;
00307          goto ABORT1;
00308        }
00309      }
00310      ABORT1:
00311      X__Free(pts[0]);
00312      X__Free(pts);
00313      if(bAbort)return;
00314      GranularityU=n->properties.GranularityMin;
00315      GranularityV=n->properties.GranularityMax;
00316      if((pts=CreateSurfaceNet(n,GranularityU,GranularityV)) == NULL)return;
00317      for(j = 0; j < GranularityU+1; j++)
00318      for(i = 0; i < GranularityV; i++){
00319        v1->xyz[0]=(long)(pts[i][j].point[0]);
00320        v1->xyz[1]=(long)(pts[i][j].point[1]);
00321        v1->xyz[2]=(long)(pts[i][j].point[2]);
00322        v2->xyz[0]=(long)(pts[i+1][j].point[0]);
00323        v2->xyz[1]=(long)(pts[i+1][j].point[1]);
00324        v2->xyz[2]=(long)(pts[i+1][j].point[2]);
00325        if(in_modeller_view(v1,v2)){
00326          flag=0;
00327          m4by1(trr,(double)v1->xyz[0],(double)v1->xyz[1],(double)v1->xyz[2]
00328                   ,&x1,&y1,&z1);
00329          m4by1(trr,(double)v2->xyz[0],(double)v2->xyz[1],(double)v2->xyz[2]
00330                   ,&x2,&y2,&z2);
00331          if(y1 >= 0.0){
00332            ix1=(int)(pwincx+scale*x1);
00333            iy1=(int)(pwincy-scale*z1);
00334          }
00335          else  flag=1;
00336          if(y2 >= 0.0){
00337            ix2=(int)(pwincx+scale*x2);
00338            iy2=(int)(pwincy-scale*z2);
00339          }
00340          else flag=1;
00341          if(flag == 0){// && (!Preferences.quick_trick || abs(ix1-ix2) > 2 || abs(iy1-iy2) > 2) ){
00342            MoveToEx(hdc,ix1,iy1,NULL);
00343            LineTo(hdc,ix2,iy2);
00344          }
00345        }
00346        if(abort && HIWORD(GetQueueStatus(QS_MOUSEMOVE)) == QS_MOUSEMOVE){
00347          bAbort=TRUE;
00348          goto ABORT2;
00349        }
00350      }
00351      ABORT2:
00352      X__Free(pts[0]);
00353      X__Free(pts);
00354      if(bAbort)return;
00355    }
00356    n=n->last;
00357  }
00358  return;
00359 }
00360 
00361 static BOOL CALLBACK TriangulateNurbsDlgProc(HWND hwnd, UINT msg,
00362                                     WPARAM wparam, LPARAM lparam){
00363  struct GRAN {int u,v;} *gran;
00364  BOOL err;
00365  int i;
00366  switch( msg ) {
00367    case WM_PAINT:
00368      PaintDialogBackground(hwnd,ghinst_main);
00369      break;
00370    case WM_INITDIALOG:{
00371        gran=(struct GRAN *)lparam;
00372        SetDlgItemInt(hwnd,DLG_MESHNURBS_U,gran->u,FALSE);
00373        SendDlgItemMessage(hwnd,DLG_MESHNURBS_U,EM_LIMITTEXT,(WPARAM)6,0);
00374        SendDlgItemMessage(hwnd,DLG_MESHNURBS_U_S,SPNM_SETRANGE,0,
00375                           MAKELPARAM(3,100));
00376        SendDlgItemMessage(hwnd,DLG_MESHNURBS_U_S,SPNM_SETCRNTVALUE,
00377                           (WPARAM)gran->u,0);
00378        SendDlgItemMessage(hwnd,DLG_MESHNURBS_U_S,SPNM_SETEDITCTRL,0,
00379                           (LPARAM)GetDlgItem(hwnd,DLG_MESHNURBS_U));
00380        SetDlgItemInt(hwnd,DLG_MESHNURBS_V,gran->v,FALSE);
00381        SendDlgItemMessage(hwnd,DLG_MESHNURBS_V,EM_LIMITTEXT,(WPARAM)6,0);
00382        SendDlgItemMessage(hwnd,DLG_MESHNURBS_V_S,SPNM_SETRANGE,0,
00383                           MAKELPARAM(3,100));
00384        SendDlgItemMessage(hwnd,DLG_MESHNURBS_V_S,SPNM_SETCRNTVALUE,
00385                           (WPARAM)gran->v,0);
00386        SendDlgItemMessage(hwnd,DLG_MESHNURBS_V_S,SPNM_SETEDITCTRL,0,
00387                           (LPARAM)GetDlgItem(hwnd,DLG_MESHNURBS_V));
00388        SetWindowLong(hwnd,GWL_USERDATA,lparam);
00389        CentreDialogOnCursor(hwnd);
00390      }
00391      return (TRUE);
00392    case WM_COMMAND:
00393       switch(LOWORD(wparam)){
00394         case IDCANCEL:
00395           EndDialog(hwnd,FALSE);
00396           return(TRUE);
00397         case IDOK:
00398           gran=(struct GRAN *)GetWindowLong(hwnd,GWL_USERDATA);
00399           gran->u=GetDlgItemInt(hwnd,DLG_MESHNURBS_U,&err,FALSE);
00400           if(!err)EndDialog(hwnd,FALSE);
00401           gran->v=GetDlgItemInt(hwnd,DLG_MESHNURBS_V,&err,FALSE);
00402           EndDialog(hwnd,TRUE);
00403           return(TRUE);
00404         default:
00405           break;
00406       }
00407       break;
00408     default: break;
00409  }
00410  return(FALSE);
00411 }
00412 
00413 void TriangulateNurbsSurface(void){
00414  struct GRAN {int u,v;} gran;
00415  nurbs *n;
00416  register long i,j;
00417  NurbsSurfSample **pts;
00418  long GranularityU,GranularityV;
00419  long x,y,z,Vf;
00420  vertex *Vp;
00421  if(Nnurbs == 0 || MainNp == NULL)return;
00422  GranularityU=20;
00423  GranularityV=20;
00424  gran.u=GranularityU;
00425  gran.v=GranularityV;
00426  if(!DialogBoxParam(ghinst_main,MAKEINTRESOURCE(DLG_MESHNURBS),ghwnd_main,
00427                      (DLGPROC)TriangulateNurbsDlgProc,(LPARAM)(&gran)))return;
00428  GranularityU=gran.u;
00429  GranularityV=gran.v;
00430  n=MainNp; while(n != NULL){
00431    if(n->selected && !n->properties.hidden){
00432      if((pts=CreateSurfaceNet(n,GranularityU,GranularityV)) == NULL)return;
00433      Vf=Nvert;
00434      if(UpdateVertexHeap(Nvert+(GranularityU+1)*(GranularityV+1))){
00435        for(i = 0; i <= GranularityV; i++)
00436        for(j = 0; j <= GranularityU; j++){
00437           CreateVertex();
00438           Vp=(MainVp+Nvert-1);
00439           Vp->xyz[0]=(long)pts[i][j].point[0];
00440           Vp->xyz[1]=(long)pts[i][j].point[1];
00441           Vp->xyz[2]=(long)pts[i][j].point[2];
00442           Vp->gp=1; 
00443           Vp->x=pts[i][j].u;
00444           Vp->y=pts[i][j].v;
00445        }
00446        if(UpdateEdgeHeap(Nedge+(GranularityU)*(GranularityV+1) // U edges
00447                               +(GranularityV)*(GranularityU+1) // V edges
00448                               +(GranularityU)*(GranularityV))){// Cross edges
00449          if(UpdateFaceHeap(Nface+(GranularityU*GranularityV*2))){
00450            for(i = 0; i < GranularityV; i++)
00451            for(j = 0; j < GranularityU; j++){
00452              CreateEdge(Vf+i*(GranularityU+1)+j,Vf+i*(GranularityU+1)+j+1);
00453              CreateEdge(Vf+i*(GranularityU+1)+j,Vf+(i+1)*(GranularityU+1)+j);
00454              CreateEdge(Vf+i*(GranularityU+1)+j,Vf+(i+1)*(GranularityU+1)+j+1);
00455              CreateFace(Vf+i*(GranularityU+1)+j,
00456                         Vf+(i+1)*(GranularityU+1)+j,
00457                         Vf+(i+1)*(GranularityU+1)+j+1);
00458              VECCOPY(n->properties.colour,(MainFp+Nface-1)->color)
00459              (MainFp+Nface-1)->bSmooth=TRUE; // smoothing
00460              CreateFace(Vf+i*(GranularityU+1)+j,
00461                         Vf+(i+1)*(GranularityU+1)+j+1,
00462                         Vf+i*(GranularityU+1)+j+1);
00463              VECCOPY(n->properties.colour,(MainFp+Nface-1)->color)
00464              (MainFp+Nface-1)->bSmooth=TRUE; // smoothing
00465            }
00466            j=GranularityU;
00467            for(i = 0; i < GranularityV; i++){ // Last row in V
00468              CreateEdge(Vf+i*(GranularityU+1)+j,Vf+(i+1)*(GranularityU+1)+j);
00469            }
00470            for(j = 0; j < GranularityU; j++){ // Last row in U
00471              CreateEdge(Vf+(GranularityU+1)*GranularityV+j,
00472                         Vf+(GranularityU+1)*GranularityV+j+1);
00473            }
00474          }
00475        }
00476      }
00477      X__Free(pts[0]);
00478      X__Free(pts);
00479    }
00480    n=n->last;
00481  }
00482  DrawModel();
00483  return;
00484 }
00485 
00486 void EraseAllNurbs(void){
00487  nurbs *temps;
00488  while(MainNp != NULL){
00489   temps=MainNp->last;
00490   ReleaseNurbs(MainNp);
00491   X__Free(MainNp);
00492   MainNp=temps;
00493  }
00494  Nnurbs=0;
00495 }
00496 
00497 void EraseNurbs(nurbs *sp){
00498  ReleaseNurbs(sp);
00499  if(sp == MainNp){
00500    MainNp=sp->last;
00501    if(MainNp != NULL)MainNp->next=NULL;
00502    X__Free(sp);
00503    sp=MainNp;
00504  }
00505  else{
00506    (sp->next)->last=sp->last;
00507    if(sp->last != NULL)(sp->last)->next=sp->next;
00508    X__Free(sp);
00509  }
00510  Nnurbs--;
00511  return;
00512 }
00513 
00514 void CreateNurbs(void){
00515  nurbs *temp;
00516  int i,j;
00517  if((temp=(nurbs *)X__Malloc(sizeof(nurbs))) == NULL)longjmp(j_buf,0);
00518  memset(temp,0,sizeof(nurbs));
00519  if(MainNp != NULL)MainNp->next=temp;
00520  temp->last=MainNp;
00521  MainNp=temp;
00522  Nnurbs++;
00523  temp->sp=NULL;
00524  temp->numU=0;
00525  temp->numV=0;
00526  temp->orderU=0;
00527  temp->orderV=0;
00528  temp->selected=FALSE;
00529  temp->kvU=NULL;
00530  temp->kvV=NULL;
00531  temp->points=NULL;
00532  sprintf(temp->properties.name,"Patch %ld",Nnurbs-1);
00533  temp->properties.GranularityMax=30;
00534  temp->properties.GranularityMin=4;
00535  temp->properties.colour[0]=255;
00536  temp->properties.colour[1]=255;
00537  temp->properties.colour[2]=255;
00538  temp->properties.hidden=0;
00539 }
00540 
00541 void ClearNurbsSkeleton(skel *sp){
00542  nurbs *np;
00543  if(Nnurbs == 0 || MainNp == NULL)return;
00544  np=MainNp; while(np != NULL){
00545    if(np->sp == sp)np->sp=NULL;
00546    np=np->last;
00547  }
00548  return;
00549 }
00550 
00551 BOOL DeleteSelectedNurbsSurfaces(void){
00552  BOOL bUpdate=FALSE;
00553  nurbs *np,*nptemp;
00554  if(Nnurbs == 0 || MainNp == NULL)return bUpdate;
00555  np=MainNp; while(np != NULL){
00556    if(np->selected){
00557      nptemp=np->last;
00558      bUpdate=TRUE;
00559      EraseNurbs(np);
00560      np=nptemp;
00561    }
00562    else np=np->last;
00563  }
00564  return bUpdate;
00565 }
00566 
00567 void ReleaseNurbs(nurbs *n){
00568  long i;
00569  if(n->kvU != NULL)X__Free(n->kvU);
00570  n->kvU = NULL;
00571  if(n->kvV != NULL)X__Free(n->kvV);
00572  n->kvV = NULL;
00573  if(n->points == NULL)return;
00574  for(i=0;i < n->numV;i++)X__Free(n->points[i]);
00575  X__Free(n->points);
00576  n->points=NULL;
00577  return;
00578 }
00579 
00580 BOOL AllocNurbs(nurbs *n, double *ukv, double *vkv){
00581  long i;
00582  if(ukv == NULL){
00583  if((n->kvU = (double *)X__Malloc((n->numU + n->orderU) * sizeof(double)))
00584    == NULL)return FALSE;
00585  }
00586  else n->kvU = ukv;
00587  if(vkv == NULL){
00588  if((n->kvV = (double *)X__Malloc((n->numV + n->orderV) * sizeof(double)))
00589    == NULL)return FALSE;
00590  }
00591  else n->kvV = vkv;
00592  if((n->points = (vector4 **)X__Malloc((long)n->numV
00593        * (long)sizeof(vector4 *))) == NULL)return FALSE;
00594  for (i = 0; i < n->numV; i++){
00595    if((n->points[i] = (vector4 *)X__Malloc((long)n->numU
00596        * (long)sizeof(vector4))) == NULL)return FALSE;
00597  }
00598  return TRUE;
00599 }
00600 
00601 BOOL CloneNurbs(nurbs *src, nurbs *dst){
00602  long i, j;
00603  double *srcp, *dstp;
00604  nurbs *last,*next;
00605  last = dst->last;
00606  next = dst->next;
00607  *dst = *src;        /* Copy fields that don't change */
00608  dst->last=last;
00609  dst->next=next;
00610  // memcpy(dst,src,sizeof(nurbs));
00611  dst->kvU = NULL;
00612  dst->kvV = NULL;    /* So they get allocated */
00613  dst->points = NULL;
00614  if(AllocNurbs(dst,NULL,NULL) == FALSE)return FALSE;
00615  /* Copy kv's */
00616  srcp = src->kvU;
00617  dstp = dst->kvU;
00618  for(i = 0; i < src->numU + src->orderU; i++)*dstp++ = *srcp++;
00619  srcp = src->kvV;
00620  dstp = dst->kvV;
00621  for(i = 0; i < src->numV + src->orderV; i++)*dstp++ = *srcp++;
00622  /* Copy control points */
00623  for(i = 0; i < src->numV; i++)
00624  for(j = 0; j < src->numU; j++){
00625    dst->points[i][j] = src->points[i][j];
00626  }
00627 //{char str[256];
00628 //sprintf(str,"Dest U %ld V %ld  Orders %ld %ld",dst->numU,dst->numV,
00629 //dst->orderU,dst->orderV);
00630 //MessageBox(NULL,str,"Copy Allocated",MB_OK);
00631 //}
00632  return TRUE;
00633 }
00634 
00635 static NurbsSurfSample **CreateSurfaceNet(nurbs *n,
00636                                           long GranularityU,
00637                                           long GranularityV){
00638  register long i,j;
00639  register double u,v;
00640  NurbsSurfSample **pts;
00641  if((pts=(NurbsSurfSample**)X__Malloc((GranularityV+1L)*sizeof(NurbsSurfSample*)))
00642    == NULL)return NULL;
00643  if((pts[0]=(NurbsSurfSample*)X__Malloc((GranularityV+1L)*(GranularityU+1L)
00644         * sizeof(NurbsSurfSample))) == NULL)return NULL;
00645  for(i = 1; i <= GranularityV; i++)
00646    pts[i] = &(pts[0][(GranularityU+1L) * i]);
00647  for (i = 0; i <= GranularityV; i++){
00648    v = ((double) i / (double) GranularityV)
00649      * (n->kvV[n->numV] - n->kvV[n->orderV-1])
00650      + n->kvV[n->orderV-1];
00651    for (j = 0; j <= GranularityU; j++){
00652      u = ((double) j / (double) GranularityU)
00653        * (n->kvU[n->numU] - n->kvU[n->orderU-1])
00654        + n->kvU[n->orderU-1];
00655      CalcPoint(u,v,n,pts[i][j].point,NULL,NULL);
00656      pts[i][j].u = u;
00657      pts[i][j].v = v;
00658    }
00659  }
00660  return pts;
00661 }

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