00001
00002
00003
00004
00005
00006
00007
00008 #define MODULE_NURBS 1
00009
00010 #include "design.h"
00011 #include "..\animate\spin_dll.h"
00012
00013 #define MAXORDER 20
00014
00015
00016
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){
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
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
00109 long knots[] = { 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4 };
00110
00111 long i,j;
00112 double r2over2 = sqrt( 2.0 ) / 2.0;
00113 double weight;
00114
00115 torus->numU = 9;
00116 torus->numV = 9;
00117 torus->orderU = 3;
00118 torus->orderV = 3;
00119
00120
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
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
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
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
00152 torus->numU = 4;
00153 torus->numV = 4;
00154 torus->orderU = 4;
00155 torus->orderV = 4;
00156 AllocNurbs(torus,NULL,NULL);
00157 for(i = 0; i < 4; i++){
00158 for(j = 0; j < 4; j++){
00159
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
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){
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){
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){
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){
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){
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){
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){
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){
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){
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){
00820
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