NURBSDLG.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 
00025 /* File NURBSDLG.C   included in NURBS.C */
00026 
00027 static BOOL CALLBACK AddNurbsDlgProc(HWND hwnd, UINT msg,
00028                                     WPARAM wparam, LPARAM lparam){
00029  long orderU=4,orderV=4,numU=4,numV=4;
00030  BOOL err;
00031  int i;
00032  nurbs *np;
00033  switch( msg ) {
00034    case WM_PAINT:
00035      PaintDialogBackground(hwnd,ghinst_main);
00036      break;
00037    case WM_INITDIALOG:{
00038        np=(nurbs *)lparam;
00039        SendDlgItemMessage(hwnd,DLG_ADDNURBS_NAME,WM_SETTEXT,0,
00040                           (LPARAM)np->properties.name);
00041        SetDlgItemInt(hwnd,DLG_ADDNURBS_ORDERU,orderU,FALSE);
00042        SendDlgItemMessage(hwnd,DLG_ADDNURBS_ORDERU,EM_LIMITTEXT,(WPARAM)6,0);
00043        SendDlgItemMessage(hwnd,DLG_ADDNURBS_ORDERU_S,SPNM_SETRANGE,0,
00044                           MAKELPARAM(3,100));
00045        SendDlgItemMessage(hwnd,DLG_ADDNURBS_ORDERU_S,SPNM_SETCRNTVALUE,
00046                           (WPARAM)orderU,0);
00047        SendDlgItemMessage(hwnd,DLG_ADDNURBS_ORDERU_S,SPNM_SETEDITCTRL,0,
00048                           (LPARAM)GetDlgItem(hwnd,DLG_ADDNURBS_ORDERU));
00049        SetDlgItemInt(hwnd,DLG_ADDNURBS_ORDERV,orderV,FALSE);
00050        SendDlgItemMessage(hwnd,DLG_ADDNURBS_ORDERV,EM_LIMITTEXT,(WPARAM)6,0);
00051        SendDlgItemMessage(hwnd,DLG_ADDNURBS_ORDERV_S,SPNM_SETRANGE,0,
00052                           MAKELPARAM(3,100));
00053        SendDlgItemMessage(hwnd,DLG_ADDNURBS_ORDERV_S,SPNM_SETCRNTVALUE,
00054                           (WPARAM)orderV,0);
00055        SendDlgItemMessage(hwnd,DLG_ADDNURBS_ORDERV_S,SPNM_SETEDITCTRL,0,
00056                           (LPARAM)GetDlgItem(hwnd,DLG_ADDNURBS_ORDERV));
00057        SetDlgItemInt(hwnd,DLG_ADDNURBS_NUMU,numU,FALSE);
00058        SendDlgItemMessage(hwnd,DLG_ADDNURBS_NUMU,EM_LIMITTEXT,(WPARAM)6,0);
00059        SendDlgItemMessage(hwnd,DLG_ADDNURBS_NUMU_S,SPNM_SETRANGE,0,
00060                           MAKELPARAM(3,100));
00061        SendDlgItemMessage(hwnd,DLG_ADDNURBS_NUMU_S,SPNM_SETCRNTVALUE,
00062                           (WPARAM)numU,0);
00063        SendDlgItemMessage(hwnd,DLG_ADDNURBS_NUMU_S,SPNM_SETEDITCTRL,0,
00064                           (LPARAM)GetDlgItem(hwnd,DLG_ADDNURBS_NUMU));
00065        SetDlgItemInt(hwnd,DLG_ADDNURBS_NUMV,numV,FALSE);
00066        SendDlgItemMessage(hwnd,DLG_ADDNURBS_NUMV,EM_LIMITTEXT,(WPARAM)6,0);
00067        SendDlgItemMessage(hwnd,DLG_ADDNURBS_NUMV_S,SPNM_SETRANGE,0,
00068                           MAKELPARAM(3,100));
00069        SendDlgItemMessage(hwnd,DLG_ADDNURBS_NUMV_S,SPNM_SETCRNTVALUE,
00070                           (WPARAM)numV,0);
00071        SendDlgItemMessage(hwnd,DLG_ADDNURBS_NUMV_S,SPNM_SETEDITCTRL,0,
00072                           (LPARAM)GetDlgItem(hwnd,DLG_ADDNURBS_NUMV));
00073        SetWindowLong(hwnd,GWL_USERDATA,lparam);
00074        CentreDialogOnCursor(hwnd);
00075      }
00076      return (TRUE);
00077    case WM_DRAWITEM:{
00078        LPDRAWITEMSTRUCT lpdis;
00079        HBRUSH   hbr,hbrold;
00080        BYTE r,g,b;
00081        lpdis=(LPDRAWITEMSTRUCT)lparam;
00082        if(lpdis->CtlID == DLG_ADDNURBS_COLOUR){
00083          np=(nurbs *)GetWindowLong(hwnd,GWL_USERDATA);
00084          r=np->properties.colour[0];
00085          g=np->properties.colour[1];
00086          b=np->properties.colour[2];
00087          if(lpdis->itemState & ODS_SELECTED)
00088             InvertRect(lpdis->hDC,&(lpdis->rcItem));
00089          else{
00090            hbr=CreateSolidBrush(RGB(r,g,b));
00091            hbrold=SelectObject(lpdis->hDC,hbr);
00092            Rectangle(lpdis->hDC,lpdis->rcItem.left,lpdis->rcItem.top,
00093                          lpdis->rcItem.right,lpdis->rcItem.bottom);
00094            SelectObject(lpdis->hDC,hbrold);
00095            DeleteObject(hbr);
00096          }
00097        }
00098      }
00099      return TRUE;
00100    case WM_COMMAND:
00101       switch(LOWORD(wparam)){
00102         case DLG_ADDNURBS_COLOUR:
00103           np=(nurbs *)GetWindowLong(hwnd,GWL_USERDATA);
00104           SetSfxColour(np->properties.colour,IDX_MISC_CHOOSE_COLOUR,hwnd);
00105           InvalidateRect(GetDlgItem(hwnd,DLG_ADDNURBS_COLOUR),NULL,FALSE);
00106           break;
00107         case IDCANCEL:
00108           EndDialog(hwnd,FALSE);
00109           return(TRUE);
00110         case IDOK:
00111           np=(nurbs *)GetWindowLong(hwnd,GWL_USERDATA);
00112           orderU=GetDlgItemInt(hwnd,DLG_ADDNURBS_ORDERU,&err,FALSE);
00113           if(!err)EndDialog(hwnd,FALSE);
00114           orderV=GetDlgItemInt(hwnd,DLG_ADDNURBS_ORDERV,&err,FALSE);
00115           if(!err)EndDialog(hwnd,FALSE);
00116           numU=GetDlgItemInt(hwnd,DLG_ADDNURBS_NUMU,&err,FALSE);
00117           if(!err)EndDialog(hwnd,FALSE);
00118           numV=GetDlgItemInt(hwnd,DLG_ADDNURBS_NUMV,&err,FALSE);
00119           if(!err)EndDialog(hwnd,FALSE);
00120           if(GetDlgItemText(hwnd,DLG_ADDNURBS_NAME,
00121              np->properties.name,31) == 0)EndDialog(hwnd,FALSE);
00122           orderU=max(orderU,3);
00123           orderV=max(orderV,3);
00124           numU=max(numU,orderU);
00125           numV=max(numV,orderV);
00126           {
00127             BOOL bI;
00128             long i,j,k,knot,multiplicity;
00129             double weight=1.0,width=10.0,length=10.0;
00130             np->numU = numU;
00131             np->numV = numV;
00132             np->orderU = orderU;
00133             np->orderV = orderV;
00134             AllocNurbs(np,NULL,NULL);
00135             for(i = 0; i < numV; i++){
00136               for(j = 0; j < numU; j++){
00137                 np->points[i][j].x = NpointerX + ((double)j/(double)(numU-1)
00138                                    * (double)MINUNIT)
00139                                    * width * weight;
00140                 np->points[i][j].y = NpointerY + ((double)i/(double)(numV-1)
00141                                    * (double)MINUNIT)
00142                                    * length * weight;
00143                 np->points[i][j].z = (NpointerZ)*weight;
00144                 np->points[i][j].w = weight;
00145                 np->points[i][j].selected = FALSE;
00146               }
00147             }
00148             multiplicity=1;
00149 //            multiplicity=orderU-1;
00150             for(knot = 1, k = 0,i = 0; i < (numU+orderU); i++){
00151               if(i < orderU){
00152                 np->kvU[i]=0.0;
00153                 bI=FALSE;
00154               }
00155               else if(i < numU){
00156                 np->kvU[i] = (double)knot;
00157                 if((++k) == multiplicity){
00158                   k=0;
00159                   knot++;
00160                   bI=FALSE;
00161                 }
00162                 else bI=TRUE;
00163               }
00164               else {
00165                 np->kvU[i] = (bI ? (double)(knot+1) : (double)knot);
00166               }
00167             }
00168             multiplicity=1;
00169 //            multiplicity=orderV-1;
00170             for(knot = 1, k = 0,i = 0; i < (numV+orderV); i++){
00171               if(i < orderV){
00172                 np->kvV[i]=0.0;
00173                 bI=FALSE;
00174               }
00175               else if(i < numV){
00176                 np->kvV[i] = (double)knot;
00177                 if((++k) == multiplicity){
00178                   k=0;
00179                   knot++;
00180                   bI=FALSE;
00181                 }
00182                 else bI=TRUE;
00183               }
00184               else {
00185                 np->kvV[i] = (bI ? (double)(knot+1) : (double)knot);
00186               }
00187             }
00188 #if 0
00189             for(i = 0; i < (numU+orderU); i++){
00190               if(i < orderU){
00191                 np->kvU[i]=0.0;
00192               }
00193               else if(i < numU){
00194                 np->kvU[i] = (double)(i-orderU+1);
00195               }
00196               else {
00197                 np->kvU[i] = (double)(numU-orderU+1);
00198               }
00199             }
00200             for(i = 0; i < (numV+orderV); i++){
00201               if(i < orderV){
00202                  np->kvV[i]=0.0;
00203               }
00204               else if(i < numV){
00205                 np->kvV[i] = (double)(i-orderV+1);
00206               }
00207               else {
00208                 np->kvV[i] = (double)(numV-orderV+1);
00209               }
00210             }
00211 #endif
00212           }
00213           EndDialog(hwnd,TRUE);
00214           return(TRUE);
00215         default:
00216           break;
00217       }
00218       break;
00219     default: break;
00220  }
00221  return(FALSE);
00222 }
00223 
00224 static BOOL CALLBACK NurbsWeightsDlgProc(HWND hwnd, UINT msg,
00225                                          WPARAM wparam, LPARAM lparam){
00226  char str[32];
00227  double wt;
00228  BOOL err;
00229  switch( msg ) {
00230    case WM_PAINT:
00231      PaintDialogBackground(hwnd,ghinst_main);
00232      break;
00233    case WM_INITDIALOG:{
00234       SendDlgItemMessage(hwnd,DLG_NURBSWEIGHTS_VALUE,WM_SETTEXT,0,
00235                         (LPARAM)"1.0");
00236        CentreDialogOnCursor(hwnd);
00237      }
00238      return TRUE;
00239    case WM_COMMAND:
00240       switch(LOWORD(wparam)){
00241         case DLG_ADDNURBS_COLOUR:
00242         case IDCANCEL:
00243           EndDialog(hwnd,TRUE);
00244         case IDOK:
00245           if(GetDlgItemText(hwnd,DLG_NURBSWEIGHTS_VALUE,
00246              str,31) != 0){
00247           wt=atof(str);
00248           if(wt > 0.0){
00249             nurbs *np;
00250             long i,j;
00251             double xp,yp,zp,w;
00252             vector4 *p1;
00253             np=MainNp; while(np != NULL){
00254               if(np->selected){
00255                 EDIT_ACTION=YES;
00256                 for(i=0;i<np->numV;i++)
00257                 for(j=0;j<np->numU;j++){
00258                   p1 = &(np->points[i][j]);
00259                   if(p1->selected){
00260                   w=1.0/p1->w;
00261                     xp=((p1->x)*w);
00262                     yp=((p1->y)*w);
00263                     zp=((p1->z)*w);
00264                     w=wt;
00265                     p1->w=w;
00266                     p1->x = xp*w;
00267                     p1->y = yp*w;
00268                     p1->z = zp*w;
00269                   }
00270                 }
00271               }
00272               np=np->last;
00273             }
00274             DrawModel();
00275           }
00276         }
00277         break;
00278       }
00279       break;
00280     default: break;
00281  }
00282  return(FALSE);
00283 }
00284 
00285 static BOOL CALLBACK NurbsSplitDlgProc(HWND hwnd, UINT msg,
00286                                        WPARAM wparam, LPARAM lparam){
00287 #define DIVX(rpt,pt ) \
00288     { (pt[0]) = (rpt)->x / (rpt)->w; \
00289       (pt[1]) = (rpt)->y / (rpt)->w; \
00290       (pt[2]) = (rpt)->z / (rpt)->w; }
00291  char str[32];
00292  BOOL err;
00293  switch( msg ) {
00294    case WM_PAINT:
00295      PaintDialogBackground(hwnd,ghinst_main);
00296      break;
00297    case WM_INITDIALOG:{
00298        SendDlgItemMessage(hwnd,DLG_NURBSSPLIT_U,BM_SETCHECK,1,0);
00299        CentreDialogOnCursor(hwnd);
00300      }
00301      return TRUE;
00302    case WM_COMMAND:
00303       switch(LOWORD(wparam)){
00304         case IDCANCEL:
00305           EndDialog(hwnd,FALSE);
00306           break;
00307         case IDOK:{
00308           long i,j;
00309           BOOL dirflag;
00310           nurbs *np,*next,*kid0,*kid1,*k0n,*k0l,*k1n,*k1l;
00311           if(SendDlgItemMessage(hwnd,DLG_NURBSSPLIT_U,BM_GETCHECK,0,0))
00312                dirflag=TRUE;
00313           else dirflag=FALSE;
00314           np=MainNp; while(np != NULL){
00315             next=np->last;
00316             if(np->selected){
00317               np->flatV = FALSE;
00318               np->flatU = FALSE;
00319               np->strU0 = FALSE;
00320               np->strUn = FALSE;
00321               np->strV0 = FALSE;
00322               np->strVn = FALSE;
00323               DIVX(&(np->points[0L][0L]),                  np->c00.point);
00324               DIVX(&(np->points[0L][np->numU-1L]),         np->c0n.point);
00325               DIVX(&(np->points[np->numV-1L][0L]),         np->cn0.point);
00326               DIVX(&(np->points[np->numV-1L][np->numU-1L]),np->cnn.point);
00327               GetNormal(np, 0L, 0L );
00328               GetNormal(np, 0L, (np->numU)-1);
00329               GetNormal(np, (np->numV)-1, 0L );
00330               GetNormal(np, (np->numV)-1, (np->numU)-1 );
00331               CreateNurbs(); kid0=MainNp;
00332               CreateNurbs(); kid1=MainNp;
00333               k0n=kid0->next; k0l=kid0->last;
00334               k1n=kid1->next; k1l=kid1->last;
00335               SplitSurface(np,kid0,kid1,dirflag);
00336               kid0->next=k0n; kid0->last=k0l;
00337               kid1->next=k1n; kid1->last=k1l;
00338               kid0->selected=FALSE;
00339               kid1->selected=FALSE;
00340               for(i=0;i<kid0->numV;i++)
00341               for(j=0;j<kid0->numU;j++)kid0->points[i][j].selected=FALSE;
00342               for(i=0;i<kid1->numV;i++)
00343               for(j=0;j<kid1->numU;j++)kid1->points[i][j].selected=FALSE;
00344               EraseNurbs(np);
00345             }
00346             np=next;
00347           }
00348           EndDialog(hwnd,TRUE);
00349         }
00350         break;
00351       }
00352       break;
00353     default: break;
00354  }
00355  return(FALSE);
00356 #undef DIVX
00357 }
00358 
00359 static long SplitKVat(double * srckv,
00360                       double ** destkv,
00361                       double kv,       // new knot value
00362                       long n, long k){ // n = numU/V  k = orderU/V
00363  double minK,maxK;
00364  long i,sp,extra=1;
00365  minK=srckv[0];
00366  maxK=srckv[n+k-1];
00367  kv=minK+kv*(maxK-minK);
00368  for(i=0;i<n+k;i++){
00369    if(srckv[i] <= kv)sp=i;
00370    if(srckv[i] == kv)extra=0;  // don't add control points if knot exists
00371  }
00372  if((*destkv = (double *)X__Malloc((long)(sizeof(double)
00373                * (n+k+extra)))) == NULL)return 0;
00374  for(i=0;i<=sp;i++)(*destkv)[i]=srckv[i];
00375  if(extra == 1)(*destkv)[sp+1]=kv;
00376  for(i=sp+1;i<n+k;i++)(*destkv)[i+extra]=srckv[i];
00377  return extra;
00378 }
00379 
00380 static BOOL CALLBACK NurbsIknotDlgProc(HWND hwnd, UINT msg,
00381                                        WPARAM wparam, LPARAM lparam){
00382  BOOL err;
00383  char str[32];
00384  double kv=0.5;
00385  switch( msg ) {
00386    case WM_PAINT:
00387      PaintDialogBackground(hwnd,ghinst_main);
00388      break;
00389    case WM_INITDIALOG:{
00390        SendDlgItemMessage(hwnd,DLG_NURBSIKNOT_U,BM_SETCHECK,1,0);
00391        SendDlgItemMessage(hwnd,DLG_NURBSIKNOT_CORNER,BM_SETCHECK,0,0);
00392        sprintf(str,"%lf",kv);
00393        SendDlgItemMessage(hwnd,DLG_NURBSIKNOT_VALUE,WM_SETTEXT,0,(LPARAM)str);
00394        CentreDialogOnCursor(hwnd);
00395      }
00396      return TRUE;
00397    case WM_COMMAND:
00398       switch(LOWORD(wparam)){
00399         case IDCANCEL:
00400           EndDialog(hwnd,FALSE);
00401           break;
00402         case IDOK:{
00403           BOOL dirflag,corner;
00404           nurbs *np,*next,*n,*p;
00405           double *newkv;
00406           long i,j,splitPt,e;
00407           if(SendDlgItemMessage(hwnd,DLG_NURBSIKNOT_U,BM_GETCHECK,0,0))
00408                dirflag=TRUE;
00409           else dirflag=FALSE;
00410           if(SendDlgItemMessage(hwnd,DLG_NURBSIKNOT_CORNER,BM_GETCHECK,0,0))
00411                corner=TRUE;
00412           else corner=FALSE;
00413           if(GetDlgItemText(hwnd,DLG_NURBSIKNOT_VALUE,str,31) != 0){
00414             kv=atof(str); kv=max(0.0,kv); kv=min(1.0,kv);
00415           }
00416           np=MainNp; while(np != NULL){
00417             next=np->last;
00418             if(np->selected){
00419               CreateNurbs(); n=MainNp->next; p=MainNp->last;
00420               *MainNp = *np; MainNp->next=n; MainNp->last=p;
00421               if(dirflag){
00422                 MainNp->numU = np->numU + (e = (corner ?
00423                   SplitKV(np->kvU,&newkv,&splitPt,(np->numU)-1,np->orderU) :
00424                   SplitKVat(np->kvU,&newkv,kv,np->numU,np->orderU)));
00425                 AllocNurbs(MainNp,newkv,NULL);
00426                 for(i=0L;i<MainNp->numV+MainNp->orderV;i++)
00427                   MainNp->kvV[i] = np->kvV[i];
00428               }
00429               else{
00430                 MainNp->numV = np->numV + (e = (corner ?
00431                   SplitKV(np->kvV,&newkv,&splitPt,(np->numV)-1,np->orderV) :
00432                   SplitKVat(np->kvV,&newkv,kv,np->numV,np->orderV)));
00433                 AllocNurbs(MainNp,NULL,newkv);
00434                 for(i=0L;i<MainNp->numU+MainNp->orderU;i++)
00435                   MainNp->kvU[i] = np->kvU[i];
00436               }
00437               if(e == 0){
00438                 MessageBox(hwnd,"Knot already exists",NULL,MB_OK);
00439               }
00440               RefineSurface(np,MainNp,dirflag);
00441               for(i=0;i<MainNp->numV;i++)
00442               for(j=0;j<MainNp->numU;j++)MainNp->points[i][j].selected=FALSE;
00443               EraseNurbs(np);
00444             }
00445             np=next;
00446           }
00447           EndDialog(hwnd,TRUE);
00448         }
00449         break;
00450       }
00451       break;
00452     default: break;
00453  }
00454  return(FALSE);
00455 }

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