00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <stdlib.h>
00027 #include <stdio.h>
00028 #include <math.h>
00029 #include <windows.h>
00030
00031 #ifdef __cplusplus
00032 extern "C" {
00033 #endif
00034
00035 #include "struct.h"
00036 #include "dstruct.h"
00037
00038 #ifdef __cplusplus
00039 }
00040 #endif
00041
00042 #include "subdcurv.h"
00043
00044 #define DESELECTED 0
00045 #define SELECTED 1
00046 #define HIDDEN 2
00047 #define INEDITOR 3
00048 #define FAIL -1
00049 #define OK 1
00050
00051 static HWND hParent;
00052 static HINSTANCE hThisInstance;
00053
00054 #if __WATCOMC__
00055 int APIENTRY LibMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00056 #else
00057 BOOL WINAPI DllMain(HANDLE hDLL, DWORD dwReason, LPVOID lpReserved){
00058 #endif
00059 switch (dwReason) {
00060 case DLL_PROCESS_ATTACH: {
00061 hThisInstance=(HINSTANCE)hDLL;
00062 if(hDLL == NULL)MessageBox ( GetFocus()," NULL instance",NULL, MB_OK);
00063 break;
00064 }
00065 case DLL_PROCESS_DETACH:
00066 break;
00067 }
00068 return TRUE;
00069 }
00070
00071 #if __SC__
00072 #pragma startaddress(DllMain)
00073 #endif
00074
00075 static int Subdivide(long, long);
00076 static void SmoothOutCurve(long, long *, BOOL);
00077
00078 extern "C" BOOL _Xmodeler
00079 (HWND parent_window,HWND info_window,X__STRUCTURE *lpevi){
00080 lpEVI=lpevi;
00081 hParent=parent_window;
00082
00083
00084
00085 {
00086 HCURSOR hSave;
00087 if(NvertSelect == 0 || NvertSelect > 32000)return FALSE;
00088 hSave=SetCursor(LoadCursor(NULL,IDC_WAIT));
00089 Subdivide(0,0);
00090 SetCursor(hSave);
00091 }
00092 return TRUE;
00093 }
00094
00095 #define VECCOPY(a,b) { b[0] = a[0]; b[1] = a[1]; b[2] = a[2]; }
00096 #define VECSUB(a,b,c) { c[0]=a[0]-b[0]; c[1]=a[1]-b[1]; c[2]=a[2]-b[2];}
00097 #define VECSUM(a,b,c) { c[0]=a[0]+b[0]; c[1]=a[1]+b[1]; c[2]=a[2]+b[2];}
00098 #define VECSCALE(a,b,c) { c[0]=(a)*b[0]; c[1]=(a)*b[1]; c[2]=(a)*b[2];}
00099 #define DOT(a,b) ( (a[0]*b[0]) + (a[1]*b[1]) + (a[2]*b[2]) )
00100 #define CROSS(v1,v2,r) { \
00101 r[0] = (v1[1]*v2[2]) - (v2[1]*v1[2]); \
00102 r[1] = (v1[2]*v2[0]) - (v1[0]*v2[2]); \
00103 r[2] = (v1[0]*v2[1]) - (v2[0]*v1[1]); \
00104 }
00105
00106 typedef struct tagVERTEXVERTEX{
00107 long vl,vr;
00108 } VERTEXVERTEX;
00109
00110 typedef struct tagFACEEXTRA{
00111 long extra,xxtra;
00112 } FACEEXTRA;
00113
00114 #include "splines.c"
00115
00116 BOOL intriview(vertex *vp){
00117 if(vp->status == HIDDEN)return FALSE;
00118 if( ((vp->xyz[0] > TVpointX) && (vp->xyz[0] < TVpointX+TVsizeX))
00119 && ((vp->xyz[1] > TVpointY) && (vp->xyz[1] < TVpointY+TVsizeY))
00120 && ((vp->xyz[2] > TVpointZ) && (vp->xyz[2] < TVpointZ+TVsizeZ))
00121 )return TRUE;
00122 return FALSE;
00123 }
00124
00125 BOOL IdentifyCurve(long *Np, long **Va, BOOL *loop){
00126 vertex *Vp;
00127 long vp,vf,*va;
00128 double d,dmin,drange;
00129 long Npath;
00130 *Va=NULL;
00131 *Np=0;
00132 if(NvertSelect < 1)return FALSE;
00133 if(NvertSelect > 1000)return FALSE;
00134 dmin=(double)TVsizeX*(double)TVsizeX;
00135 drange=dmin/1024;
00136 vp=0; vf= -1;
00137 while(vp < Nvert){
00138 Vp=(MainVp+vp);
00139 if(Vp->status == SELECTED && intriview(Vp)){
00140 d=(double)(Vp->xyz[0]-NpointerX)*(double)(Vp->xyz[0]-NpointerX)
00141 +(double)(Vp->xyz[1]-NpointerY)*(double)(Vp->xyz[1]-NpointerY)
00142 +(double)(Vp->xyz[2]-NpointerZ)*(double)(Vp->xyz[2]-NpointerZ);
00143 if(d < dmin && d < drange){
00144 dmin=d;
00145 vf=vp;
00146 }
00147 }
00148 Vp->id=0;
00149 vp++;
00150 }
00151 if(vf < 0)return FALSE;
00152 if((va=(long *)X__Malloc(NvertSelect*sizeof(long))) == NULL){
00153 return FALSE;
00154 }
00155 *Va=va;
00156 Npath=0; va[0]=vf; (MainVp+va[0])->id=1;
00157 vp=0; while(vp < Nvert){
00158 Vp=(MainVp+vp);
00159 if(Vp->status == SELECTED && Vp->id == 0 && Connected(va[Npath],vp)){
00160 Npath++;
00161 va[Npath]=vp;
00162 Vp->id=1;
00163 vp=0;
00164 }
00165 else vp++;
00166 }
00167 if(Connected(va[Npath],va[0]))*loop = TRUE;
00168 else *loop = FALSE;
00169 if(*loop){
00170 if((va=(long *)X__Realloc(va,(Npath+2)*sizeof(long))) == NULL){
00171 return FALSE;
00172 }
00173 *Va=va;
00174 Npath++;
00175 va[Npath]=va[0];
00176 }
00177 Npath++;
00178 if(Npath < 4)return FALSE;
00179 *Np=Npath;
00180 return TRUE;
00181 }
00182
00183 static int Subdivide(long down_to_f, long down_to_e){
00184 face *fp;
00185 edge *ep;
00186 vertex *vp,*V0,*V1,*V2;
00187 long i,j,vl,vr,id,nf=0,ne=0,n,Nedge1,Nface1,Nv1;
00188 long Npath=0,*Vpath=NULL;
00189 VERTEXVERTEX *vlist=NULL;
00190 FACEEXTRA *MainLp=NULL,*lp;
00191 HCURSOR hSave;
00192 BOOL loop;
00193
00194 if(!IdentifyCurve(&Npath,&Vpath,&loop)){
00195 if(Vpath != NULL)X__Free(Vpath);
00196 return FAIL;
00197 }
00198 for(i=0;i<Npath;i++)(MainVp+Vpath[i])->status=INEDITOR;
00199 X__Free(Vpath);
00200
00201 for(i=0;i<Nvert;i++){
00202 if( (MainVp+i)->status == SELECTED)(MainVp+i)->status=INEDITOR;
00203 else if((MainVp+i)->status == INEDITOR)(MainVp+i)->status=SELECTED;
00204 }
00205
00206 if(down_to_f < Nface){
00207 if((MainLp=(FACEEXTRA *)X__Malloc(Nface*sizeof(FACEEXTRA))) == NULL){
00208 return FAIL;
00209 }
00210 fp=(MainFp+down_to_f); lp=(MainLp+down_to_f); nf=0;
00211 for(i=down_to_f;i<Nface;i++){
00212 lp->extra = -1;
00213 lp->xxtra = -1;
00214 V0=(MainVp+fp->V[0]); V1=(MainVp+fp->V[1]); V2=(MainVp+fp->V[2]);
00215 if((V0->status == SELECTED && V1->status == SELECTED) ||
00216 (V1->status == SELECTED && V2->status == SELECTED) ||
00217 (V2->status == SELECTED && V0->status == SELECTED)){
00218 nf++;
00219 }
00220 fp++; lp++;
00221 }
00222 }
00223 for(ep=(MainEp+down_to_e),ne=0,i=down_to_e;i<Nedge;i++){
00224 if((MainVp+ep->V[0])->status == SELECTED &&
00225 (MainVp+ep->V[1])->status == SELECTED)ne++;
00226 ep++;
00227 }
00228 if(ne == 0){
00229 if(MainLp != NULL)X__Free(MainLp);
00230 return FAIL;
00231 }
00232
00233 if((vlist=(VERTEXVERTEX *)X__Malloc(ne*sizeof(VERTEXVERTEX))) == NULL){
00234 if(MainLp != NULL)X__Free(MainLp);
00235 return FAIL;
00236 }
00237 if(!UpdateVertexHeap(Nvert+ne))goto EP1;
00238 if(!UpdateEdgeHeap(Nedge+ne+nf*3))goto EP1;
00239 if(!UpdateFaceHeap(Nface+nf*3))goto EP1;
00240 Nface1=Nface; Nedge1=Nedge;
00241 ep=(MainEp+down_to_e); n=0;
00242 for(i=down_to_e;i<Nedge1;i++){
00243 vl=ep->V[0]; V0=(MainVp+vl); vr=ep->V[1]; V1=(MainVp+vr);
00244 if(V0->status == SELECTED && V1->status == SELECTED){
00245 CreateVertex(); Nv1=Nvert-1;
00246 vlist[n].vl=vl; vlist[n].vr=vr; (MainVp+Nv1)->id=n; n++;
00247 (MainVp+Nv1)->xyz[0]=(V0->xyz[0] + V1->xyz[0])/2;
00248 (MainVp+Nv1)->xyz[1]=(V0->xyz[1] + V1->xyz[1])/2;
00249 (MainVp+Nv1)->xyz[2]=(V0->xyz[2] + V1->xyz[2])/2;
00250 CreateEdge(Nv1,ep->V[1]);
00251 ep->V[1]=Nv1;
00252 if(down_to_f < Nface1){
00253 fp=(MainFp+down_to_f); lp=(MainLp+down_to_f);
00254 for(j=down_to_f;j<Nface1;j++){
00255 id=0;
00256 if ((fp->V[0] == vl && fp->V[1] == vr) ||
00257 (fp->V[0] == vr && fp->V[1] == vl) )id=1;
00258 else if((fp->V[1] == vl && fp->V[2] == vr) ||
00259 (fp->V[1] == vr && fp->V[2] == vl) )id=2;
00260 else if((fp->V[2] == vl && fp->V[0] == vr) ||
00261 (fp->V[2] == vr && fp->V[0] == vl) )id=3;
00262 if(id != 0){
00263 if(lp->extra < 0)lp->extra=Nv1;
00264 else{
00265 if(lp->xxtra < 0)lp->xxtra=Nv1;
00266 else{
00267 CreateEdge(Nv1,lp->extra);
00268 CreateEdge(Nv1,lp->xxtra);
00269 CreateEdge(lp->extra,lp->xxtra);
00270 if (id == 1){
00271 if(IsFOSame(fp->V[0],fp->V[1],fp->V[2],
00272 fp->V[2],lp->xxtra,lp->extra))
00273 CreateFace(fp->V[2],lp->xxtra,lp->extra);
00274 else
00275 CreateFace(fp->V[2],lp->extra,lp->xxtra);
00276 CopyFaceProp(fp,(MainFp+Nface-1));
00277 if(vlist[(MainVp+lp->extra)->id].vl == fp->V[0] ||
00278 vlist[(MainVp+lp->extra)->id].vr == fp->V[0]){
00279 if(IsFOSame(fp->V[0],fp->V[1],fp->V[2],
00280 fp->V[0],Nv1,lp->extra))
00281 CreateFace(fp->V[0],Nv1,lp->extra);
00282 else
00283 CreateFace(fp->V[0],lp->extra,Nv1);
00284 CopyFaceProp(fp,(MainFp+Nface-1));
00285 if(IsFOSame(fp->V[0],fp->V[1],fp->V[2],
00286 fp->V[1],Nv1,lp->xxtra))
00287 CreateFace(fp->V[1],Nv1,lp->xxtra);
00288 else
00289 CreateFace(fp->V[1],lp->xxtra,Nv1);
00290 CopyFaceProp(fp,(MainFp+Nface-1));
00291 }
00292 else{
00293 if(IsFOSame(fp->V[0],fp->V[1],fp->V[2],
00294 fp->V[1],Nv1,lp->extra))
00295 CreateFace(fp->V[1],Nv1,lp->extra);
00296 else
00297 CreateFace(fp->V[1],lp->extra,Nv1);
00298 CopyFaceProp(fp,(MainFp+Nface-1));
00299 if(IsFOSame(fp->V[0],fp->V[1],fp->V[2],
00300 fp->V[0],Nv1,lp->xxtra))
00301 CreateFace(fp->V[0],Nv1,lp->xxtra);
00302 else
00303 CreateFace(fp->V[0],lp->xxtra,Nv1);
00304 CopyFaceProp(fp,(MainFp+Nface-1));
00305 }
00306 }
00307 else if(id == 2){
00308 if(IsFOSame(fp->V[0],fp->V[1],fp->V[2],
00309 fp->V[0],lp->xxtra,lp->extra))
00310 CreateFace(fp->V[0],lp->xxtra,lp->extra);
00311 else
00312 CreateFace(fp->V[0],lp->extra,lp->xxtra);
00313 CopyFaceProp(fp,(MainFp+Nface-1));
00314 if(vlist[(MainVp+lp->extra)->id].vl == fp->V[1] ||
00315 vlist[(MainVp+lp->extra)->id].vr == fp->V[1]){
00316 if(IsFOSame(fp->V[0],fp->V[1],fp->V[2],
00317 fp->V[1],Nv1,lp->extra))
00318 CreateFace(fp->V[1],Nv1,lp->extra);
00319 else
00320 CreateFace(fp->V[1],lp->extra,Nv1);
00321 CopyFaceProp(fp,(MainFp+Nface-1));
00322 if(IsFOSame(fp->V[0],fp->V[1],fp->V[2],
00323 fp->V[2],Nv1,lp->xxtra))
00324 CreateFace(fp->V[2],Nv1,lp->xxtra);
00325 else
00326 CreateFace(fp->V[2],lp->xxtra,Nv1);
00327 CopyFaceProp(fp,(MainFp+Nface-1));
00328 }
00329 else{
00330 if(IsFOSame(fp->V[0],fp->V[1],fp->V[2],
00331 fp->V[2],Nv1,lp->extra))
00332 CreateFace(fp->V[2],Nv1,lp->extra);
00333 else
00334 CreateFace(fp->V[2],lp->extra,Nv1);
00335 CopyFaceProp(fp,(MainFp+Nface-1));
00336 if(IsFOSame(fp->V[0],fp->V[1],fp->V[2],
00337 fp->V[1],Nv1,lp->xxtra))
00338 CreateFace(fp->V[1],Nv1,lp->xxtra);
00339 else
00340 CreateFace(fp->V[1],lp->xxtra,Nv1);
00341 CopyFaceProp(fp,(MainFp+Nface-1));
00342 }
00343 }
00344 else if(id == 3){
00345 if(IsFOSame(fp->V[0],fp->V[1],fp->V[2],
00346 fp->V[1],lp->xxtra,lp->extra))
00347 CreateFace(fp->V[1],lp->xxtra,lp->extra);
00348 else
00349 CreateFace(fp->V[1],lp->extra,lp->xxtra);
00350 CopyFaceProp(fp,(MainFp+Nface-1));
00351 if(vlist[(MainVp+lp->extra)->id].vl == fp->V[2] ||
00352 vlist[(MainVp+lp->extra)->id].vr == fp->V[2]){
00353 if(IsFOSame(fp->V[0],fp->V[1],fp->V[2],
00354 fp->V[2],Nv1,lp->extra))
00355 CreateFace(fp->V[2],Nv1,lp->extra);
00356 else
00357 CreateFace(fp->V[2],lp->extra,Nv1);
00358 CopyFaceProp(fp,(MainFp+Nface-1));
00359 if(IsFOSame(fp->V[0],fp->V[1],fp->V[2],
00360 fp->V[0],Nv1,lp->xxtra))
00361 CreateFace(fp->V[0],Nv1,lp->xxtra);
00362 else
00363 CreateFace(fp->V[0],lp->xxtra,Nv1);
00364 CopyFaceProp(fp,(MainFp+Nface-1));
00365 }
00366 else{
00367 if(IsFOSame(fp->V[0],fp->V[1],fp->V[2],
00368 fp->V[0],Nv1,lp->extra))
00369 CreateFace(fp->V[0],Nv1,lp->extra);
00370 else
00371 CreateFace(fp->V[0],lp->extra,Nv1);
00372 CopyFaceProp(fp,(MainFp+Nface-1));
00373 if(IsFOSame(fp->V[0],fp->V[1],fp->V[2],
00374 fp->V[2],Nv1,lp->xxtra))
00375 CreateFace(fp->V[2],Nv1,lp->xxtra);
00376 else
00377 CreateFace(fp->V[2],lp->xxtra,Nv1);
00378 CopyFaceProp(fp,(MainFp+Nface-1));
00379 }
00380 }
00381 if(IsFOSame(fp->V[0],fp->V[1],fp->V[2],
00382 lp->xxtra,lp->extra,Nv1)){
00383 fp->V[0]=lp->xxtra;
00384 fp->V[1]=lp->extra;
00385 fp->V[2]=Nv1;
00386 }
00387 else{
00388 fp->V[0]=lp->xxtra;
00389 fp->V[1]=Nv1;
00390 fp->V[2]=lp->extra;
00391 }
00392 lp->extra = -1;
00393 lp->xxtra = -1;
00394 }
00395 }
00396 }
00397 fp++; lp++;
00398 }
00399 }
00400 }
00401 ep++;
00402 }
00403 if(down_to_f < Nface1){
00404 fp=(MainFp+down_to_f); lp=(MainLp+down_to_f);
00405 for(i=down_to_f;i<Nface1;i++){
00406 V0=(MainVp+fp->V[0]);
00407 V1=(MainVp+fp->V[1]);
00408 V2=(MainVp+fp->V[2]);
00409 if(lp->extra >= 0){
00410 if(V0->status == DESELECTED){
00411 if( IsFOSame(fp->V[0],fp->V[1],fp->V[2],
00412 fp->V[0],lp->extra,fp->V[2]))
00413 CreateFace(fp->V[0],lp->extra,fp->V[2]);
00414 else
00415 CreateFace(fp->V[0],fp->V[2],lp->extra);
00416 CopyFaceProp(fp,(MainFp+Nface-1));
00417 CreateEdge(fp->V[0],lp->extra);
00418 fp->V[2] = lp->extra;
00419 }
00420 else if(V1->status == DESELECTED){
00421 if( IsFOSame(fp->V[0],fp->V[1],fp->V[2],
00422 fp->V[1],lp->extra,fp->V[0]))
00423 CreateFace(fp->V[1],lp->extra,fp->V[0]);
00424 else
00425 CreateFace(fp->V[1],fp->V[0],lp->extra);
00426 CopyFaceProp(fp,(MainFp+Nface-1));
00427 CreateEdge(fp->V[1],lp->extra);
00428 fp->V[0] = lp->extra;
00429 }
00430 else if(V2->status == DESELECTED){
00431 if( IsFOSame(fp->V[0],fp->V[1],fp->V[2],
00432 fp->V[2],lp->extra,fp->V[1]))
00433 CreateFace(fp->V[2],lp->extra,fp->V[1]);
00434 else
00435 CreateFace(fp->V[2],fp->V[1],lp->extra);
00436 CopyFaceProp(fp,(MainFp+Nface-1));
00437 CreateEdge(fp->V[2],lp->extra);
00438 fp->V[1] = lp->extra;
00439 }
00440 }
00441 fp++; lp++;
00442 }
00443 }
00444 X__Free(vlist);
00445 if(MainLp != NULL)X__Free(MainLp);
00446
00447 if(!IdentifyCurve(&Npath,&Vpath,&loop)){
00448 if(Vpath != NULL)X__Free(Vpath);
00449 return FAIL;
00450 }
00451
00452 for(i=0;i<Nvert;i++){
00453 if((MainVp+i)->status == INEDITOR)(MainVp+i)->status=SELECTED;
00454 }
00455
00456 SmoothOutCurve(Npath,Vpath,loop);
00457 X__Free(Vpath);
00458 return OK;
00459 EP1:
00460 if(MainLp != NULL)X__Free(MainLp);
00461 X__Free(vlist);
00462 return FAIL;
00463 }
00464
00465 static void SmoothOutCurve(long Npath, long *Vpath, BOOL loop){
00466 long c,i,j,l,n;
00467 double vl,v1,v2,vn,k[4];
00468
00469
00470
00471
00472 for(i=0;i<Npath-2;i+=2){
00473 for(c=0;c<3;c++){
00474 j=i+2;
00475 v1=(double)(MainVp+Vpath[i])->xyz[c];
00476 v2=(double)(MainVp+Vpath[j])->xyz[c];
00477 if(i == 0){
00478 if(loop)vl=(double)(MainVp+Vpath[Npath-3])->xyz[c];
00479 else vl=(double)(2*((MainVp+Vpath[i])->xyz[c]) -
00480 (MainVp+Vpath[j])->xyz[c]);
00481 vn=(double)(MainVp+Vpath[j+2])->xyz[c];
00482 }
00483 else if(i == Npath-3){
00484 vl=(double)(MainVp+Vpath[i-2])->xyz[c];
00485 if(loop)vn=(double)(MainVp+Vpath[2])->xyz[c];
00486 else vn=(double)(2*((MainVp+Vpath[j])->xyz[c]) -
00487 (MainVp+Vpath[i])->xyz[c]);
00488 }
00489 else{
00490 vl=(double)(MainVp+Vpath[i-2])->xyz[c];
00491 vn=(double)(MainVp+Vpath[j+2])->xyz[c];
00492 }
00493 SplinesK(k,vl,v1,v2,vn);
00494 (MainVp+Vpath[i+1])->xyz[c] = (long)SplinesR(k,0.5);
00495 }
00496 }
00497 return;
00498 }