00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #define MODULE_UTILS 1
00011
00012 #include "design.h"
00013
00014 char *TruncateTextString(char *input, char *output, long length){
00015 if(strlen(input) < length)return input;
00016 strncpy(output,input,3); output[3]='\0';
00017 strcat(output,"....\\");
00018 strcat(output,FileInPath(input));
00019 if(strlen(output) > length)return FileInPath(input);
00020 return output;
00021 }
00022
00023 static long VertexHeapSize=0,EdgeHeapSize=0,FaceHeapSize=0;
00024
00036 void EraseAll(short what){
00037 char filename[MAX_DIR];
00038 long i,j;
00039 if(MainFp != NULL)X__Free(MainFp); MainFp=NULL;
00040 if(MainVp != NULL)X__Free(MainVp); MainVp=NULL;
00041 if(MainEp != NULL)X__Free(MainEp); MainEp=NULL;
00042 Nvert=0; Nface=0; Nedge=0; NvertSelect=0; NvertDeselect=0;
00043 VertexHeapSize=0,EdgeHeapSize=0,FaceHeapSize=0;
00044 if(Bcurves != NULL && N_Bcurves > 0){
00045 for(i=0;i<N_Bcurves;i++){
00046 if(Bcurves[i].Vc != NULL)X__Free(Bcurves[i].Vc);
00047 if(Bcurves[i].Vp != NULL)X__Free(Bcurves[i].Vp);
00048 }
00049 X__Free(Bcurves); Bcurves=NULL; N_Bcurves=0;
00050 }
00051 EraseAllSkeleton();
00052 EraseAllNurbs();
00053 if(what == 0)return;
00054 if(nImaps > 0){
00055 for(i=0;i<nImaps;i++){
00056 if(iMap[i].s && iMap[i].S != NULL)X__Free(iMap[i].S);
00057 iMap[i].S=NULL; iMap[i].s=0;
00058 if(iMap[i].r && iMap[i].R != NULL)X__Free(iMap[i].R);
00059 iMap[i].R=NULL; iMap[i].r=0;
00060 if(iMap[i].b && iMap[i].B != NULL)X__Free(iMap[i].B);
00061 iMap[i].B=NULL; iMap[i].b=0;
00062 if(iMap[i].t && iMap[i].T != NULL)X__Free(iMap[i].T);
00063 iMap[i].T=NULL; iMap[i].t=0;
00064 UnloadRamImage(&(iMap[i].si));
00065 UnloadRamImage(&(iMap[i].ri));
00066 UnloadRamImage(&(iMap[i].bi));
00067 UnloadRamImage(&(iMap[i].ti));
00068 }
00069 nImaps=0; nLockediMaps=0;
00070 }
00071 if(nMats > 0){
00072 for(i=0;i<nMats;i++)for(j=0;j<4;j++){
00073 if(iMat[i].Shader[j].in_use && iMat[i].Shader[j].parameters != NULL)X__Free(iMat[i].Shader[j].parameters);
00074 if(iMat[i].Shader[j].in_use && iMat[i].Shader[j].xname != NULL)X__Free(iMat[i].Shader[j].xname);
00075 }
00076 }
00077 nMats=0;
00078 if(w_frame.p != NULL)X__Free(w_frame.p); w_frame.p=NULL; w_frame.Np=0;
00079 if(w_frame.e != NULL)X__Free(w_frame.e); w_frame.e=NULL; w_frame.Ne=0;
00080 ShadowFlag=NO;
00081 MirrorFlag = -1;
00082 CheckMenuItem(GetMenu(ghwnd_main),IDM_ATTRIBUTES_SHADOW,MF_UNCHECKED);
00083 ObjectAxis.Origin.xyz[0]=ObjectAxis.Origin.xyz[1]=ObjectAxis.Origin.xyz[2]=0;
00084 ObjectAxis.Offset.xyz[0]=ObjectAxis.Offset.xyz[1]=ObjectAxis.Offset.xyz[2]=0;
00085 GetTriview(TRUE);
00086 grid_size=UNIT;
00087 NpointerX=0; NpointerY=0; NpointerZ=0;
00088 sprintf(filename,"%sW_$.SCR",TempPath);
00089 remove(filename);
00090 sprintf(filename,"%sW_$.MFX",TempPath);
00091 remove(filename);
00092 EDIT_ACTION=NO;
00093 }
00094
00095 void EraseAllSkeleton(void){
00096 skel *temps;
00097 long i;
00098 if(Nvert > 0)for(i=0;i<Nvert;i++){
00099 (MainVp+i)->sp=NULL;
00100 }
00101 while(MainSp != NULL)
00102 { temps=MainSp->last; X__Free(MainSp); MainSp=temps;
00103 } Nskel=0;
00104 CreateSkeleton(NULL);
00105 FirstSp=MainSp;
00106 current_skeleton=FirstSp;
00107 FirstSp->xyz[0]=FirstSp->xyz[1]=FirstSp->xyz[2]=0;
00108 UpdateSkTreeView();
00109 }
00110
00111 void Delete_Bcurve(void){
00112 long i,j,n,flag=1;
00113 long *v;
00114 vertex *Vp;
00115 if(Bcurves == NULL || N_Bcurves == 0)return;
00116 for(i=0;i<N_Bcurves;i++){
00117 Bcurves[i].flag=0;
00118 if((v=Bcurves[i].Vc) != NULL)for(j=0;j<Bcurves[i].Nc;j++){
00119 if(Vp->status == SELECTED){Bcurves[i].flag=1; flag=0; break;}
00120 }
00121 if((v=Bcurves[i].Vp) != NULL)for(j=0;j<Bcurves[i].Np;j++){
00122 Vp=(MainVp+v[j]);
00123 if(Vp->status == SELECTED){Bcurves[i].flag=1; flag=0; break;}
00124 }
00125 }
00126 if(flag)return;
00127 n=N_Bcurves-1;
00128 for(i=n;i>=0;i--){
00129 if(Bcurves[i].flag){
00130 if(Bcurves[i].Vc != NULL)X__Free(Bcurves[i].Vc);
00131 if(Bcurves[i].Vp != NULL)X__Free(Bcurves[i].Vp);
00132 if(i < N_Bcurves-1){
00133 for(j=i;j<N_Bcurves-1;j++){
00134 Bcurves[j].Nc = Bcurves[j+1].Nc; Bcurves[j].Vc = Bcurves[j+1].Vc;
00135 Bcurves[j].Np = Bcurves[j+1].Np; Bcurves[j].Vp = Bcurves[j+1].Vp;
00136 strcpy(Bcurves[j].name,Bcurves[j+1].name);
00137 }
00138 }
00139 N_Bcurves--;
00140 }
00141 }
00142
00143 Bcurves = (bezier_curve *)X__Realloc(Bcurves,sizeof(bezier_curve)*N_Bcurves);
00144 if(Bcurves == NULL)N_Bcurves=0;
00145
00146
00147 }
00148
00149 void Delete_MapLock(void){
00150 long i;
00151 vertex *vp0,*vp1,*vp2;
00152 if(nLockediMaps == 0)return;
00153 for(i=0;i<nImaps;i++){
00154 if(iMap[i].Lock){
00155 vp0=(MainVp+iMap[i].Vlock[0]);
00156 vp1=(MainVp+iMap[i].Vlock[1]);
00157 vp2=(MainVp+iMap[i].Vlock[2]);
00158 if(vp0->status == SELECTED ||
00159 vp1->status == SELECTED ||
00160 vp2->status == SELECTED){
00161 iMap[i].Lock=0;
00162 nLockediMaps--;
00163 }
00164 }
00165 }
00166 if(nLockediMaps < 0)nLockediMaps=0;
00167 }
00168
00169 void RecalibrateMapLocks(void){
00170 long i,j;
00171 if(nLockediMaps == 0)return;
00172 for(i=0;i<nImaps;i++){
00173 if(iMap[i].Lock){
00174 for(j=0;j<3;j++){
00175 iMap[i].P[j] = (MainVp+iMap[i].Vlock[0])->xyz[j];
00176 iMap[i].X[j] = (MainVp+iMap[i].Vlock[1])->xyz[j];
00177 iMap[i].Y[j] = (MainVp+iMap[i].Vlock[2])->xyz[j];
00178 }
00179 }
00180 }
00181 }
00182
00183 short EraseSkeleton(skel *thisone){
00184 skel *sp,*sptemp;
00185 if(thisone == FirstSp){
00186 SendPrgmQuery(IDQ_NODELETESKROOT,0);
00187 return 0;
00188 }
00189
00190 current_skeleton=thisone->at;
00191 sp=MainSp;
00192 while(sp != NULL){
00193 if(sp->at == thisone)sp->at = thisone->at;
00194 sp=sp->last;
00195 }
00196 sp=MainSp;
00197 while(sp != NULL){
00198 if(sp == thisone){
00199 if(sp == MainSp){
00200 MainSp=sp->last;
00201 if(MainSp != NULL)MainSp->next=NULL;
00202 X__Free(sp); sp=MainSp;
00203 }
00204 else{
00205 (sp->next)->last=sp->last;
00206 if(sp->last != NULL)(sp->last)->next=sp->next;
00207 sptemp=sp->last;
00208 X__Free(sp);
00209 sp=sptemp;
00210 }
00211 Nskel--;
00212 return 1;
00213 }
00214 sp=sp->last;
00215 }
00216 return 0;
00217 }
00218
00219 int EraseEdge(int mem_update){
00220 int idid=NO;
00221 long i,NewC;
00222 face *fp;
00223 edge *ep;
00224 vertex *V0,*V1,*V2;
00225 NewC=Nface; fp=MainFp; if(MainFp != NULL)for(i=0;i<Nface;i++){
00226 V0=(MainVp+fp->V[0]); V1=(MainVp+fp->V[1]); V2=(MainVp+fp->V[2]);
00227 if( (V0->status == SELECTED && V1->status == SELECTED)
00228 ||(V1->status == SELECTED && V2->status == SELECTED)
00229 ||(V2->status == SELECTED && V0->status == SELECTED) ){
00230 if(i < Nface-1)CopyMemory(fp,(MainFp+NewC-1),sizeof(face));
00231 NewC--;
00232 }
00233 else fp++;
00234 }
00235 if(NewC != Nface){
00236 idid=YES;
00237 Nface=NewC;
00238 if(mem_update)UpdateFaceHeap(Nface);
00239 }
00240 NewC=Nedge; ep=MainEp; if(MainEp != NULL)for(i=0;i<Nedge;i++){
00241 V0=(MainVp+ep->V[0]); V1=(MainVp+ep->V[1]);
00242 if(V0->status == SELECTED && V1->status == SELECTED){
00243 if(i < Nedge-1)CopyMemory(ep,(MainEp+NewC-1),sizeof(edge));
00244 NewC--;
00245 }
00246 else ep++;
00247 }
00248 if(NewC != Nedge){
00249 idid=YES;
00250 Nedge=NewC;
00251 if(mem_update)UpdateEdgeHeap(Nedge);
00252 }
00253 return idid;
00254 }
00255
00256 int EraseVertex(int mem_update){
00257 int idid=NO;
00258 long i,k,NewC;
00259 vertex *vp,*vo;
00260 face *fp;
00261 edge *ep;
00262 vertex *V0,*V1,*V2;
00263 NewC=Nface; fp=MainFp; if(MainFp != NULL)for(i=0;i<Nface;i++){
00264 V0=(MainVp+fp->V[0]); V1=(MainVp+fp->V[1]); V2=(MainVp+fp->V[2]);
00265 if( V0->status == SELECTED
00266 || V1->status == SELECTED
00267 || V2->status == SELECTED ){
00268 if(i < Nface-1)CopyMemory(fp,(MainFp+NewC-1),sizeof(face));
00269 NewC--;
00270 }
00271 else fp++;
00272 }
00273 if(NewC != Nface){
00274 idid=YES;
00275 Nface=NewC;
00276 if(mem_update)UpdateFaceHeap(Nface);
00277 }
00278 NewC=Nedge; ep=MainEp; if(MainEp != NULL)for(i=0;i<Nedge;i++){
00279 V0=(MainVp+ep->V[0]); V1=(MainVp+ep->V[1]);
00280 if(V0->status == SELECTED || V1->status == SELECTED){
00281 if(i < Nedge-1)CopyMemory(ep,(MainEp+NewC-1),sizeof(edge));
00282 NewC--;
00283 }
00284 else ep++;
00285 }
00286 if(NewC != Nedge){
00287 idid=YES;
00288 Nedge=NewC;
00289 if(mem_update)UpdateEdgeHeap(Nedge);
00290 }
00291 Delete_Bcurve(); Delete_MapLock();
00292 NewC=Nvert; vp=MainVp; if(MainVp != NULL)for(i=0,k=0;i<Nvert;i++){
00293 if(vp->status == SELECTED){
00294 NvertSelect--;
00295 if(i < Nvert-1){
00296 vo=(MainVp+NewC-1);
00297 CopyMemory(vp,vo,sizeof(vertex));
00298 vo->id=k;
00299 }
00300 NewC--;
00301 }
00302 else {
00303 vp++; k++;
00304 }
00305 }
00306 if(NewC != Nvert){
00307 idid=YES;
00308 Nvert=NewC;
00309
00310 if(Nface > 0 && MainFp != NULL)for(i=0,fp=MainFp;i<Nface;i++,fp++){
00311 if(fp->V[0] >= Nvert)fp->V[0]=(MainVp+fp->V[0])->id;
00312 if(fp->V[1] >= Nvert)fp->V[1]=(MainVp+fp->V[1])->id;
00313 if(fp->V[2] >= Nvert)fp->V[2]=(MainVp+fp->V[2])->id;
00314 }
00315 if(Nedge > 0 && MainEp != NULL)for(i=0,ep=MainEp;i<Nedge;i++,ep++){
00316 if(ep->V[0] >= Nvert)ep->V[0]=(MainVp+ep->V[0])->id;
00317 if(ep->V[1] >= Nvert)ep->V[1]=(MainVp+ep->V[1])->id;
00318 }
00319 if(mem_update)UpdateVertexHeap(Nvert);
00320 }
00321 return idid;
00322 }
00323
00324 void EraseVertexMapping(void){
00325 int i;
00326 vertex *vp;
00327 if(MainVp != NULL && Nvert > 0)for(vp=MainVp,i=0;i<Nvert;i++,vp++){
00328 if(vp->gp == 1){
00329 vp->gp = 0;
00330 }
00331 }
00332 }
00333
00334 void CreateEdge(long v1, long v2){
00335 if(Nedge+1 > EdgeHeapSize)MessageBeep(MB_OK);
00336 if(Nedge+1 > EdgeHeapSize)UpdateEdgeHeap(Nedge+1);
00337 (MainEp+Nedge)->V[0]=v1;
00338 (MainEp+Nedge)->V[1]=v2;
00339 Nedge++;
00340 }
00341
00342 void CreateFace(long v1, long v2, long v3){
00343 face *temp;
00344 if(Nface+1 > FaceHeapSize)MessageBeep(MB_OK);
00345 if(Nface+1 > FaceHeapSize)UpdateFaceHeap(Nface+1);
00346 temp=(MainFp+Nface);
00347 temp->V[0]=v1;
00348 temp->V[1]=v2;
00349 temp->V[2]=v3;
00350 temp->color[0]=FaceColour[0];
00351 temp->color[1]=FaceColour[1];
00352 temp->color[2]=FaceColour[2];
00353 temp->imagemap=-1;
00354 temp->material=-1;
00355 temp->gp=FALSE;
00356 temp->x[0]=temp->x[1]=temp->x[2]=0.0;
00357 temp->y[0]=temp->y[1]=temp->y[2]=0.0;
00358 temp->bSmooth=FALSE;
00359 Nface++;
00360 }
00361
00362 void CreateVertex(void){
00363 vertex *temp;
00364 if(Nvert+1 > VertexHeapSize)MessageBeep(MB_OK);
00365 if(Nvert+1 > VertexHeapSize)UpdateVertexHeap(Nvert+1);
00366 temp=(MainVp+Nvert);
00367 temp->xyz[0]=NpointerX;
00368 temp->xyz[1]=NpointerY;
00369 temp->xyz[2]=NpointerZ;
00370 temp->status=SELECTED;
00371 temp->sp = NULL;
00372 temp->gp = 0;
00373 temp->x=0.0; temp->y=0.0;
00374 Nvert++;
00375 NvertSelect++;
00376 }
00377
00378 BOOL UpdateVertexHeap(long n){
00379 vertex *temp;
00380 if(n == VertexHeapSize)return TRUE;
00381 if(n == 0){
00382 if(MainVp != NULL)X__Free(MainVp);
00383 temp=NULL;
00384 }
00385 else if(VertexHeapSize == 0){
00386 if((temp=(vertex *)X__Malloc(n*sizeof(vertex))) == NULL)longjmp(j_buf,0);
00387 }
00388 else{
00389 if((temp=(vertex *)X__Realloc(MainVp,n*sizeof(vertex))) == NULL)longjmp(j_buf,0);
00390 }
00391 MainVp=temp;
00392 VertexHeapSize=n;
00393 return TRUE;
00394 }
00395
00396 BOOL UpdateEdgeHeap(long n){
00397 edge *temp;
00398 if(n == EdgeHeapSize)return TRUE;
00399 if(n == 0){
00400 if(MainEp != NULL)X__Free(MainEp);
00401 temp=NULL;
00402 }
00403 else if(EdgeHeapSize == 0){
00404 if((temp=(edge *)X__Malloc(n*sizeof(edge))) == NULL)longjmp(j_buf,0);
00405 }
00406 else{
00407 if((temp=(edge *)X__Realloc(MainEp,n*sizeof(edge))) == NULL)longjmp(j_buf,0);
00408 }
00409 MainEp=temp;
00410 EdgeHeapSize=n;
00411 return TRUE;
00412 }
00413
00414 BOOL UpdateFaceHeap(long n){
00415 face *temp;
00416 if(n == FaceHeapSize)return TRUE;
00417 if(n == 0){
00418 if(MainFp != NULL)X__Free(MainFp);
00419 temp=NULL;
00420 }
00421 else if(FaceHeapSize == 0){
00422 if((temp=(face *)X__Malloc(n*sizeof(face))) == NULL)longjmp(j_buf,0);
00423 }
00424 else{
00425 if((temp=(face *)X__Realloc(MainFp,n*sizeof(face))) == NULL)longjmp(j_buf,0);
00426 }
00427 MainFp=temp;
00428 FaceHeapSize=n;
00429 return TRUE;
00430 }
00431
00432 void CreateSkeleton(skel *at){
00433 skel *temp;
00434 int i,j;
00435 if(( temp=(skel *)X__Malloc(sizeof(skel)) ) == NULL)longjmp(j_buf,0);
00436 if(MainSp != NULL)MainSp->next=temp;
00437 temp->last=MainSp;
00438 temp->xyz[0]=NpointerX;
00439 temp->xyz[1]=NpointerY;
00440 temp->xyz[2]=NpointerZ;
00441 temp->next=NULL;
00442 temp->at=at;
00443 temp->id=0;
00444 temp->offset=0;
00445 temp->weight=1.0;
00446 temp->wrange=1.0;
00447 temp->wzone=0.1;
00448 temp->u[0]=1.0; temp->u[1]=0.0; temp->u[2]=0.0;
00449 temp->v[0]=0.0; temp->v[1]=1.0; temp->v[2]=0.0;
00450 temp->w[0]=0.0; temp->w[1]=0.0; temp->w[2]=1.0;
00451 temp->lParam=0;
00452 for(i=0;i<8;i++){
00453 temp->bx[i][0]=NpointerX;
00454 temp->bx[i][1]=NpointerY;
00455 temp->bx[i][2]=NpointerZ;
00456 }
00457 for(i=0;i<4;i++)for(j=0;j<4;j++){
00458 temp->t[i][j]=0.0;
00459 if(i == j)temp->t[i][j]=1.0;
00460 }
00461 MainSp=temp;
00462 Nskel++;
00463 if(Nskel == 1)strcpy(temp->name,"Root");
00464 else sprintf(temp->name,"%ld",Nskel-1);
00465 }
00466
00467 short intriview(vertex *vp){
00468 if(vp->status == HIDDEN)return 0;
00469 if( ((vp->xyz[0] > TVpointX) && (vp->xyz[0] < TVpointX+TVsizeX))
00470 && ((vp->xyz[1] > TVpointY) && (vp->xyz[1] < TVpointY+TVsizeY))
00471 && ((vp->xyz[2] > TVpointZ) && (vp->xyz[2] < TVpointZ+TVsizeZ))
00472 )return 1;
00473 return 0;
00474 }
00475
00476 int EraseIndicatedEdge(void){
00477 int i,sh1,sh2,sv1,sv2,npx,npy;
00478 double x,y,z,mu,a,b,c,d,dmin;
00479 edge *ep,*epid;
00480 vertex *vp,*vp1,*vp2;
00481 if(Nedge == 0 || MainEp == NULL || MainVp == NULL)return NO;
00482 dmin=(double)TVsizeX*(double)TVsizeX;
00483 epid=NULL;
00484 for(ep=MainEp,i=0;i<Nedge;i++,ep++){
00485 vp1=(MainVp+ep->V[0]); vp2=(MainVp+ep->V[1]);
00486 if(intriview(vp1) || intriview(vp2)){
00487 GetWindowCoords(ActiveView,
00488 vp1->xyz[0],vp1->xyz[1],vp1->xyz[2],&sh1,&sv1);
00489 GetWindowCoords(ActiveView,
00490 vp2->xyz[0],vp2->xyz[1],vp2->xyz[2],&sh2,&sv2);
00491 a=(double)(sh2-sh1); b=(double)(sv2-sv1);
00492 GetWindowCoords(ActiveView,
00493 NpointerX,NpointerY,NpointerZ,&npx,&npy);
00494 if((sh2-sh1) != 0 || (sv2-sv1) != 0){
00495 x=(double)npx; y=(double)npy;
00496 mu=(a*(x-(double)sh1) + b*(y-(double)sv1))/(a*a+b*b);
00497 if(mu > 0.0001 && mu < 0.9999){
00498 x=a*mu+(double)sh1; y=b*mu+(double)sv1;
00499 sh1=(short)x; sv1=(short)y;
00500 if(abs(npx-sh1) < 3 && abs(npy-sv1) < 3){
00501 a=(double)(vp2->xyz[0]-vp1->xyz[0]);
00502 b=(double)(vp2->xyz[1]-vp1->xyz[1]);
00503 c=(double)(vp2->xyz[2]-vp1->xyz[2]);
00504 mu=(a*((double)NpointerX-(double)(vp1->xyz[0]))
00505 +b*((double)NpointerY-(double)(vp1->xyz[1]))
00506 +c*((double)NpointerZ-(double)(vp1->xyz[2])))/(a*a+b*b+c*c);
00507 x=a*mu+(double)(vp1->xyz[0]);
00508 y=b*mu+(double)(vp1->xyz[1]);
00509 z=c*mu+(double)(vp1->xyz[2]);
00510 d=(x-(double)NpointerX)*(x-(double)NpointerX)
00511 +(y-(double)NpointerY)*(y-(double)NpointerY)
00512 +(z-(double)NpointerZ)*(z-(double)NpointerZ);
00513 if(d < dmin){
00514 dmin=d;
00515 epid=ep;
00516 }
00517 }
00518 }
00519 }
00520 }
00521 }
00522 if(epid == NULL)return NO;
00523 vp1=(MainVp+epid->V[0]); vp2=(MainVp+epid->V[1]);
00524 sh1=(int)vp1->status; sh2=(int)vp2->status;
00525 for(i=0,vp=MainVp;i<Nvert;i++){
00526 if(vp->status == SELECTED)vp->status = INEDITOR;
00527 vp++;
00528 }
00529 vp1->status=SELECTED;
00530 vp2->status=SELECTED;
00531 EraseEdge(1);
00532 for(i=0,vp=MainVp;i<Nvert;i++){
00533 if(vp->status == INEDITOR)vp->status = SELECTED;
00534 vp++;
00535 }
00536 vp1->status=(unsigned char)sh1; vp2->status=(unsigned char)sh2;
00537 return YES;
00538 }
00539
00540 int EraseIndicatedVertex(void){
00541 vertex *vp,*vps;
00542 double d,dmin;
00543 int i,sho,svo,npx,npy;
00544 if(Nvert == 0 || MainVp == NULL)return NO;
00545 dmin=(double)TVsizeX*(double)TVsizeX;
00546 vps=NULL;
00547 GetWindowCoords(ActiveView,NpointerX,NpointerY,NpointerZ,&npx,&npy);
00548 for(vp=MainVp,i=0;i<Nvert;i++,vp++){
00549 if(intriview(vp)){
00550 GetWindowCoords(ActiveView,vp->xyz[0],vp->xyz[1],vp->xyz[2],&sho,&svo);
00551 if( (sho > npx-4) && (sho < npx+4)
00552 && (svo > npy-4) && (svo < npy+4)){
00553 d=(double)(vp->xyz[0]-NpointerX)*(double)(vp->xyz[0]-NpointerX)
00554 +(double)(vp->xyz[1]-NpointerY)*(double)(vp->xyz[1]-NpointerY)
00555 +(double)(vp->xyz[2]-NpointerZ)*(double)(vp->xyz[2]-NpointerZ);
00556 if(d < dmin){
00557 dmin=d;
00558 vps=vp;
00559 }
00560 }
00561 }
00562 }
00563 if(vps == NULL)return NO;
00564 if(vps->status==DESELECTED){NvertDeselect--; NvertSelect++;}
00565 for(vp=MainVp,i=0;i<Nvert;i++,vp++){
00566 if(vp->status == SELECTED)vp->status = INEDITOR;
00567 }
00568 vps->status=SELECTED;
00569 EraseVertex(1);
00570 if(MainVp == NULL || Nvert == 0)return YES;
00571 for(vp=MainVp,i=0;i<Nvert;i++,vp++){
00572 if(vp->status == INEDITOR)vp->status = SELECTED;
00573 }
00574 return YES;
00575 }
00576
00577 BOOL CheckFaceExists(long v1, long v2, long v3, long limit){
00578 long i;
00579 face *fp;
00580 if(Nface == 0)return FALSE;
00581 fp=(MainFp+Nface-1); for(i=Nface-1;i>=limit;i--){
00582 if( ((fp->V[0] == v1) && (fp->V[1] == v2) && (fp->V[2] == v3))
00583 || ((fp->V[0] == v1) && (fp->V[1] == v3) && (fp->V[2] == v2))
00584 || ((fp->V[0] == v2) && (fp->V[1] == v3) && (fp->V[2] == v1))
00585 || ((fp->V[0] == v2) && (fp->V[1] == v1) && (fp->V[2] == v3))
00586 || ((fp->V[0] == v3) && (fp->V[1] == v1) && (fp->V[2] == v2))
00587 || ((fp->V[0] == v3) && (fp->V[1] == v2) && (fp->V[2] == v1))
00588 )return TRUE;
00589 fp--;
00590 }
00591 return FALSE;
00592 }
00593
00594 BOOL CheckEdgeExists(long v1, long v2, long limit){
00595 int i;
00596 edge *ep;
00597 if(Nedge == 0)return FALSE;
00598 ep=(MainEp+Nedge-1); for(i=Nedge-1;i>=limit;i--){
00599 if( ((ep->V[0] == v1) && (ep->V[1] == v2))
00600 || ((ep->V[0] == v2) && (ep->V[1] == v1)) )return TRUE;
00601
00602 ep--;
00603 }
00604 return FALSE;
00605 }
00606
00607 void CopyFaceProp(face *fin, face *fout){
00608 fout->color[0] = fin->color[0];
00609 fout->color[1] = fin->color[1];
00610 fout->color[2] = fin->color[2];
00611 fout->bSmooth = fin->bSmooth;
00612 fout->material=fin->material;
00613 fout->imagemap=fin->imagemap;
00614 fout->gp=fin->gp;
00615 fout->x[0]=fin->x[0]; fout->y[0]=fin->y[0];
00616 fout->x[1]=fin->x[1]; fout->y[1]=fin->y[1];
00617 fout->x[2]=fin->x[2]; fout->y[2]=fin->y[2];
00618 }
00619
00620 int IdentifyIndicatedFace(void){
00621 int i,sh1,sh2,sv1,sv2,sh3,sv3,npx,npy,shmin,shmax,svmin,svmax;
00622 double dv1[2],dv2[2],dv3[2];
00623 double l,dv12,dv23,dv31,t1,t2,t3,ta;
00624 face *fp;
00625 vertex *vp,*vp1,*vp2,*vp3;
00626 if(Nface == 0 || MainFp == NULL || MainVp == NULL)return -1;
00627
00628 for(fp=MainFp,i=0;i<Nface;i++,fp++){
00629 vp1=(MainVp+fp->V[0]); vp2=(MainVp+fp->V[1]); vp3=(MainVp+fp->V[2]);
00630 if(intriview(vp1) && intriview(vp2) && intriview(vp3) &&
00631 vp1->status == SELECTED && vp2->status == SELECTED && vp3->status == SELECTED){
00632 GetWindowCoords(ActiveView,
00633 vp1->xyz[0],vp1->xyz[1],vp1->xyz[2],&sh1,&sv1);
00634 GetWindowCoords(ActiveView,
00635 vp2->xyz[0],vp2->xyz[1],vp2->xyz[2],&sh2,&sv2);
00636 GetWindowCoords(ActiveView,
00637 vp3->xyz[0],vp3->xyz[1],vp3->xyz[2],&sh3,&sv3);
00638 GetWindowCoords(ActiveView,
00639 NpointerX,NpointerY,NpointerZ,&npx,&npy);
00640 shmin=min(sh1,min(sh2,sh3));
00641 shmax=max(sh1,max(sh2,sh3));
00642 svmin=min(sv1,min(sv2,sv3));
00643 svmax=max(sv1,max(sv2,sv3));
00644 if(npx > shmin && npx < shmax && npy > svmin && npy < svmax){
00645
00646 dv1[0]=(double)sh1-(double)npx; dv1[1]=(double)sv1-(double)npy;
00647 dv2[0]=(double)sh2-(double)npx; dv2[1]=(double)sv2-(double)npy;
00648 dv3[0]=(double)sh3-(double)npx; dv3[1]=(double)sv3-(double)npy;
00649 l=sqrt(DOT2(dv1,dv1)); dv1[0] /= l; dv1[1] /= l;
00650 l=sqrt(DOT2(dv2,dv2)); dv2[0] /= l; dv2[1] /= l;
00651 l=sqrt(DOT2(dv3,dv3)); dv3[0] /= l; dv3[1] /= l;
00652 dv12=DOT2(dv2,dv1); t1=acos(dv12)*180.0/PI;
00653 dv23=DOT2(dv3,dv2); t2=acos(dv23)*180.0/PI;
00654 dv31=DOT2(dv1,dv3); t3=acos(dv31)*180.0/PI;
00655 ta=t1+t2+t3;
00656
00657 if(ta > 359.8)return i;
00658 }
00659 }
00660 }
00661 return -1;
00662 }
00663
00664
00665
00666
00667 static void Line(void);
00668 static void Helix(int);
00669 static void Plot3D(void);
00670 static BOOL MakeLatLongSphere(long, long, long);
00671 static BOOL MakeTorus(long, long, double, long);
00672
00673 static short LastNumberSides=12;
00674
00675 void SpecialFunction(int item){
00676 switch(item){
00677 case IDM_ACTIONS_SPECIAL_3DPLOT: Plot3D(); break;
00678 case IDM_ACTIONS_SPECIAL_HELIX: Helix(0); break;
00679 case IDM_ACTIONS_SPECIAL_SPIRAL: Helix(1); break;
00680 case IDM_ACTIONS_SPECIAL_3DSPIRAL: Helix(2); break;
00681 case IDM_ACTIONS_SPECIAL_LINE: Line(); break;
00682 case IDM_ACTIONS_SPECIAL_BUTTERFLY:
00683 AddPolygon(0,TVsizeX/4,ActiveView);
00684 DrawModel();
00685 break;
00686 default: break;
00687 }
00688 UpdateCounters();
00689 }
00690
00691 static void Helix(int choice){
00692 struct np {int type,n,r;} d;
00693 double fx, fy, alpha, radius=2000.00;
00694 vertex *Vp=NULL;
00695 int range,i,spiral=0,Npoints;
00696 if((double)TVsizeX / (double)4000 <= 1.00) {
00697 SendPrgmQuery(IDQ_SCALETOOSMALL,0);
00698 return;
00699 }
00700 if(choice == 1 || choice == 2) {
00701 d.type=spiral;
00702 d.n=20;
00703 d.r=500;
00704 if(DialogBoxParam(ghinst_main,MAKEINTRESOURCE(DLG_SPIRAL),ghwnd_main,
00705 (DLGPROC)SpiralsDlgProc,(LPARAM)&d) != OK)return;
00706 spiral=d.type;
00707 Npoints=d.n;
00708 range=d.r;
00709 }
00710 else{
00711 Npoints=RequestNumEntry(20,5,90,"No of Vertices"," Vertices");
00712 range=800;
00713 }
00714 if(Npoints <= 0)return;
00715 if(!UpdateVertexHeap(Nvert+Npoints)){
00716 SendPrgmQuery(IDQ_NOMEM2,0);
00717 return;
00718 }
00719 if(!UpdateEdgeHeap(Nedge+Npoints-1)){
00720 SendPrgmQuery(IDQ_NOMEM2,0);
00721 return;
00722 }
00723 for(i=0;i<Npoints;i++) {
00724 alpha=(range/Npoints)*i;
00725 alpha=alpha*0.0175;
00726 fx=cos(alpha)*radius;
00727 fy=sin(alpha)*radius;
00728 CreateVertex();
00729 Vp=(MainVp+Nvert-1);
00730 Vp->xyz[0]=(long)fx;
00731 Vp->xyz[1]=(long)fy;
00732 Vp->xyz[0]*=TVsizeX/4000;
00733 Vp->xyz[1]*=TVsizeY/4000;
00734 Vp->xyz[0]+=NpointerX;
00735 Vp->xyz[1]+=NpointerY;
00736 if(choice == 0){
00737 Vp->xyz[2]=(long)(alpha*2000);
00738 Vp->xyz[2]*=TVsizeZ/4000;
00739 }
00740 else if(choice == 2){
00741 Vp->xyz[2]=(long)(radius);
00742 Vp->xyz[2]*=TVsizeZ/4000;
00743 }
00744 if(i > 0)CreateEdge(Nvert-1,Nvert-2);
00745 if(choice == 1 || choice == 2) {
00746 if(spiral == 0) radius-=2000/Npoints;
00747 else if(spiral == 1) radius*=1.05;
00748 }
00749 }
00750 DrawModel();
00751 }
00752
00753 void AddPolygon(int ns, long radius, int axis){
00754 double fx, fy, alpha;
00755 char x,y,z;
00756 int i,Npoints,fv;
00757 long px,py;
00758 vertex *Vp=NULL;
00759 if((double)TVsizeX / (double)4000 <= 1.00) {
00760 SendPrgmQuery(IDQ_SCALETOOSMALL,0);
00761 return;
00762 }
00763 if(ns == 0)Npoints=RequestNumEntry(LastNumberSides,4,90,
00764 "No of Sides"," Sides");
00765 else Npoints=ns;
00766 if(Npoints <= 0)return;
00767 LastNumberSides=Npoints;
00768 switch(axis) {
00769 case TRITOP: x=0; y=1; z=2; px=NpointerX; py=NpointerY; break;
00770 case TRIFRONT: x=0; y=2; z=1; px=NpointerX; py=NpointerZ; break;
00771 case TRIRIGHT: x=1; y=2; z=0; px=NpointerY; py=NpointerZ; break;
00772 default: return; break;
00773 }
00774 if(!UpdateVertexHeap(Nvert+Npoints)){
00775 SendPrgmQuery(IDQ_NOMEM2,0);
00776 return;
00777 }
00778 if(!UpdateEdgeHeap(Nedge+Npoints)){
00779 SendPrgmQuery(IDQ_NOMEM2,0);
00780 return;
00781 }
00782 for(i=0; i<Npoints; ++i) {
00783 alpha=(360.0/(double)Npoints)*(double)i;
00784 alpha*=0.0175;
00785 fx=cos(alpha)*(double)radius;
00786 fy=sin(alpha)*(double)radius;
00787 CreateVertex();
00788 Vp=(MainVp+Nvert-1);
00789 Vp->xyz[x]=(long)fx;
00790 Vp->xyz[y]=(long)fy;
00791 Vp->xyz[x]+=px;
00792 Vp->xyz[y]+=py;
00793 if(i == 0)fv=Nvert-1;
00794 else CreateEdge(Nvert-1,Nvert-2);
00795 }
00796 CreateEdge(Nvert-1,fv);
00797 }
00798
00799 static void Plot3D(void){
00800 struct np {int t,x,y;} d;
00801 long double fx, fy, fz;
00802 int choice, gridx=15, gridz=15, range=360, count, zcount;
00803 int vp,tvp,fvp = -1;
00804 vertex *Vp;
00805 if((double)TVsizeX / (double)12000 <= 1.00) {
00806 SendPrgmQuery(IDQ_SCALETOOSMALL,0);
00807 return;
00808 }
00809 d.t=0; d.x=15; d.y=15;
00810 if(DialogBoxParam(ghinst_main,MAKEINTRESOURCE(DLG_FPLOT),ghwnd_main,
00811 (DLGPROC)FunctionPlotDlgProc,(LPARAM)&d) != OK)return;
00812 choice=d.t;
00813 gridx=d.x;
00814 gridz=d.y;
00815 if(gridx < 0 || gridz < 0)return;
00816 if(!UpdateVertexHeap(Nvert+gridx*gridz)){
00817 SendPrgmQuery(IDQ_NOMEM2,0);
00818 return;
00819 }
00820 if(!UpdateEdgeHeap(Nedge+(gridx-1)*gridz+(gridz-1)*gridx+
00821 (gridx-1)*(gridz-1))){
00822 SendPrgmQuery(IDQ_NOMEM2,0);
00823 return;
00824 }
00825 if(!UpdateFaceHeap(Nface+(gridx-1)*(gridz-1)*2)){
00826 SendPrgmQuery(IDQ_NOMEM2,0);
00827 return;
00828 }
00829 for(zcount=0; zcount<gridz; ++zcount) {
00830 fz=(range/gridz)*zcount;
00831 fz=fz*0.0175;
00832 vp = -1;
00833 for(count=0; count<gridx; ++count) {
00834 fx=(range/gridx)*count;
00835 fx=fx*0.0175;
00836 switch(choice) {
00837 case 0: fy=0; break;
00838 case 1: fy=sin(fx); break;
00839 case 2: fy=tan(fx); break;
00840 case 3: fy=exp(-1*(pow(fx-PI,2)+pow(fz-PI,2))); break;
00841 case 4: fy=sin(fx)*sin(fz); break;
00842 case 5: fy=sin(fx*fz); break;
00843 case 6: fy=sin(fx)*sin(3*fz); break;
00844 case 7: fy=sin(fx)+cos(fz); break;
00845 default: break;
00846 }
00847 CreateVertex();
00848 Vp=(MainVp+Nvert-1);
00849 Vp->xyz[0]=(long)(fx*2000.00);
00850 Vp->xyz[2]=(long)(fy*2000.00);
00851 Vp->xyz[1]=(long)(fz*2000.00);
00852 Vp->xyz[0]*=TVsizeX/12000;
00853 Vp->xyz[1]*=TVsizeY/12000;
00854 Vp->xyz[2]*=TVsizeZ/12000;
00855 Vp->xyz[0]+=NpointerX;
00856 Vp->xyz[1]+=NpointerY;
00857 if(vp >= 0)CreateEdge(vp,Nvert-1);
00858 if(fvp < 0)fvp=Nvert-1;
00859 vp=Nvert-1;
00860 }
00861 }
00862 for(range=0; range<gridz-1; ++range) {
00863 for(count=0; count<gridx; ++count) {
00864 tvp=fvp+gridx;
00865 CreateEdge(tvp,fvp);
00866 if(count<gridx-1) {
00867 CreateEdge(tvp,fvp+1);
00868 CreateFace(tvp,fvp+1,fvp);
00869 CreateFace(tvp+1,fvp+1,tvp);
00870 }
00871 fvp++;
00872 }
00873 }
00874 DrawModel();
00875 }
00876
00877 static void Line(void){
00878 int Npoints=8, c;
00879 long i;
00880 double r=1.3;
00881 char response[16];
00882 vertex *Vp=NULL;
00883 if(Read1Int1Real("Create Line","Number of Vertices","Spacing Ratio",
00884 &Npoints,2,90,&r,-2.0,2.0,ghwnd_main) == FAIL)return;
00885 if(Npoints < 0) return;
00886 if(r>2.00 || r<-2.00 || r==0.00){
00887 SendPrgmQuery(IDQ_BADRATIO,0);
00888 return;
00889 }
00890 if(!UpdateVertexHeap(Nvert+Npoints)){
00891 SendPrgmQuery(IDQ_NOMEM2,0);
00892 return;
00893 }
00894 if(!UpdateEdgeHeap(Nedge+Npoints-1)){
00895 SendPrgmQuery(IDQ_NOMEM2,0);
00896 return;
00897 }
00898 i=TVpointX/Npoints;
00899 for(c=0; c<Npoints; ++c) {
00900 CreateVertex();
00901 Vp=(MainVp+Nvert-1);
00902 Vp->xyz[0]=i;
00903 Vp->xyz[1]=NpointerY;
00904 Vp->xyz[2]=NpointerZ;
00905 if(c != 0)CreateEdge(Nvert-1,Nvert-2);
00906 i = (long)((double)i*r);
00907 }
00908 DrawModel();
00909 }
00910
00911 static void RotatePointXY(point p, int angle){
00912 double theta,ctheta,stheta,dx,dy;
00913 theta = (double)angle*PI/180.0;
00914 ctheta=cos(theta);
00915 stheta=sin(theta);
00916 dx=(double)(p[0]-NpointerX);
00917 dy=(double)(p[1]-NpointerY);
00918 p[0]=NpointerX+(long)(ctheta*dx-stheta*dy);
00919 p[1]=NpointerY+(long)(stheta*dx+ctheta*dy);
00920 }
00921
00922 void UpdatePrimitiveStructure(long primitivetype, int view,
00923 long xmin, long ymin, long zmin,
00924 long xmax, long ymax, long zmax,
00925 long xc, long yc, long zc){
00926 int i,ml,mw;
00927 PrimStruct.ml=1; PrimStruct.mw=1;
00928 PrimStruct.lr=(double)(xc-lrulerx)/ruler;
00929 PrimStruct.fb=(double)(yc-lrulery)/ruler;
00930 PrimStruct.ud=(double)(zc-lrulerz)/ruler;
00931 PrimStruct.length=(double)labs(ymax-ymin)/ruler;
00932 PrimStruct.width=(double)labs(xmax-xmin)/ruler;
00933 PrimStruct.height=(double)labs(zmax-zmin)/ruler;
00934 if (view == TRITOP )PrimStruct.radius=max(PrimStruct.length,PrimStruct.width)/2.0;
00935 else if(view == TRIFRONT)PrimStruct.radius=max(PrimStruct.width,PrimStruct.height)/2.0;
00936 else if(view == TRIRIGHT)PrimStruct.radius=max(PrimStruct.length,PrimStruct.height)/2.0;
00937 switch (primitivetype){
00938 case 0:
00939 if(view == TRITOP){
00940 if(xmin > xmax)mw = -1; else mw = 1;
00941 if(ymin > ymax)ml = -1; else ml = 1;
00942 PrimStruct.width=(double)labs(xmax-xmin)/ruler;
00943 PrimStruct.length=(double)labs(ymax-ymin)/ruler;
00944 }
00945 else if(view == TRIFRONT){
00946 if(xmin > xmax)mw = -1; else mw = 1;
00947 if(zmin > zmax)ml = -1; else ml = 1;
00948 PrimStruct.width=(double)labs(xmax-xmin)/ruler;
00949 PrimStruct.length=(double)labs(zmax-zmin)/ruler;
00950 }
00951 else if(view == TRIRIGHT){
00952 if(ymin > ymax)mw = -1; else mw = 1;
00953 if(zmin > zmax)ml = -1; else ml = 1;
00954 PrimStruct.width=(double)labs(ymax-ymin)/ruler;
00955 PrimStruct.length=(double)labs(zmax-zmin)/ruler;
00956 }
00957 PrimStruct.ml=ml;
00958 PrimStruct.mw=mw;
00959 break;
00960 case 1:
00961 break;
00962 case 2:
00963 break;
00964 case 3:
00965 if (view == TRITOP )PrimStruct.length=(double)labs(zmax-zmin)/ruler;
00966 else if(view == TRIFRONT)PrimStruct.length=(double)labs(ymax-ymin)/ruler;
00967 else if(view == TRIRIGHT)PrimStruct.length=(double)labs(xmax-xmin)/ruler;
00968 break;
00969 case 4:
00970 break;
00971 case 5:
00972 if (view == TRITOP )PrimStruct.length=(double)labs(zmax-zmin)/ruler;
00973 else if(view == TRIFRONT)PrimStruct.length=(double)labs(ymax-ymin)/ruler;
00974 else if(view == TRIRIGHT)PrimStruct.length=(double)labs(xmax-xmin)/ruler;
00975 break;
00976 case 6:
00977 if (view == TRITOP )PrimStruct.length=(double)labs(zmax-zmin)/ruler;
00978 else if(view == TRIFRONT)PrimStruct.length=(double)labs(ymax-ymin)/ruler;
00979 else if(view == TRIRIGHT)PrimStruct.length=(double)labs(xmax-xmin)/ruler;
00980 break;
00981 case 7:
00982 break;
00983 case 8:
00984 break;
00985 default: break;
00986 }
00987 return;
00988 }
00989
00990 static BOOL MakeTorus(long npoly, long nring, double prop, long view){
00991
00992 long radius,view1;
00993 if (view == TRITOP){
00994 radius=prop*(TVsizeZ/4);
00995 NpointerX=TVpointX+TVsizeX-radius;
00996 view1=TRIFRONT;
00997 }
00998 else if(view == TRIFRONT){
00999 radius=prop*(TVsizeY/4);
01000 NpointerX=TVpointX+TVsizeY-radius;
01001 view1=TRITOP;
01002 }
01003 else if(view == TRIRIGHT){
01004 radius=prop*(TVsizeX/4);
01005 NpointerY=TVpointY+TVsizeX-radius;
01006 view1=TRITOP;
01007 }
01008 AddPolygon(npoly,radius,view1);
01009 NpointerX=TVpointX+TVsizeX/2;
01010 NpointerY=TVpointY+TVsizeY/2;
01011 NpointerZ=TVpointZ+TVsizeZ/2;
01012 Spin(1,nring,TRUE,view);
01013 return TRUE;
01014 }
01015
01016 static BOOL MakeLatLongSphere(long nlat, long nlong, long view){
01017 long i,j,radius,*lastrow;
01018 double dv,angle=0.0,dangle=PI/(double)(nlat-1);
01019
01020 if (view == TRITOP )dv=(double)TVsizeZ/2;
01021 else if(view == TRIFRONT)dv=(double)TVsizeY/2;
01022 else if(view == TRIRIGHT)dv=(double)TVsizeX/2;
01023 if((lastrow=(long *)X__Malloc(nlong*sizeof(long))) == NULL)return FALSE;
01024 for(i=0;i<nlat;i++){
01025
01026 if (view == TRITOP )NpointerZ=TVpointZ+TVsizeZ/2+(long)(dv*cos(angle));
01027 else if(view == TRIFRONT)NpointerY=TVpointY+TVsizeY/2+(long)(dv*cos(angle));
01028 else if(view == TRIRIGHT)NpointerX=TVpointX+TVsizeX/2+(long)(dv*cos(angle));
01029 if(i == 0){
01030 if(!UpdateVertexHeap(Nvert+1))return FALSE;
01031 CreateVertex();
01032 }
01033 else if(i == (nlat-1)){
01034 if(!UpdateVertexHeap(Nvert+1))return FALSE;
01035 CreateVertex();
01036 if(!UpdateEdgeHeap(Nedge+nlong))return FALSE;
01037 if(!UpdateFaceHeap(Nface+nlong))return FALSE;
01038 for(j=Nvert-nlong-1;j<Nvert-1;j++){
01039 CreateEdge(j,Nvert-1);
01040 if(j == Nvert-nlong-1)CreateFace(j,Nvert-2,Nvert-1);
01041 else CreateFace(j,j-1,Nvert-1);
01042 }
01043 }
01044 else {
01045 radius=(long)(dv*sin(angle));
01046 AddPolygon(nlong,radius,view);
01047 if(i == 1){
01048 if(!UpdateEdgeHeap(Nedge+nlong))return FALSE;
01049 if(!UpdateFaceHeap(Nface+nlong))return FALSE;
01050 for(j=Nvert-nlong;j<Nvert;j++){
01051 CreateEdge(j,Nvert-nlong-1);
01052 if(j == Nvert-nlong)CreateFace(j,Nvert-nlong-1,Nvert-1);
01053 else CreateFace(j,Nvert-nlong-1,j-1);
01054 }
01055 }
01056 else {
01057 if(!UpdateEdgeHeap(Nedge+2*nlong))return FALSE;
01058 if(!UpdateFaceHeap(Nface+2*nlong))return FALSE;
01059 for(j=Nvert-nlong;j<Nvert;j++){
01060 CreateEdge(j,j-nlong);
01061 if(j == Nvert-nlong){
01062 CreateEdge(j,j-1);
01063 CreateFace(j,j-nlong,j-1);
01064 CreateFace(j,j-1,j+nlong-1);
01065 }
01066 else{
01067 CreateEdge(j,j-nlong-1);
01068 CreateFace(j,j-nlong,j-nlong-1);
01069 CreateFace(j,j-nlong-1,j-1);
01070 }
01071 }
01072 }
01073 }
01074 angle += dangle;
01075 }
01076 X__Free(lastrow);
01077 return TRUE;
01078 }
01079
01080 void BuildPrimitive(long primitivetype, int view){
01081 vertex *Vp;
01082 long n_face_list,*face_list,last_face;
01083 long n,x,y,z,tvx,tvy,tvz,tvpx,tvpy,tvpz;
01084 long v1,v2,v3,v4,v5,v6,v7,v8,opx,opy,opz,dx,dy,dz,LastMainFp,
01085 LastMainEp,LastMainVp,radius,height,vs[12];
01086 int i,j,fp,vp;
01087 int fid[30]={0,6,5,
01088 6,0,1,
01089 1,7,6,
01090 7,1,2,
01091 2,8,7,
01092 8,2,3,
01093 3,9,8,
01094 9,3,4,
01095 4,5,9,
01096 5,4,0};
01097 face *Fp;
01098 x=NpointerX; y=NpointerY; z=NpointerZ;
01099 tvx=TVsizeX; tvy=TVsizeY; tvz=TVsizeZ;
01100 tvpx=TVpointX; tvpy=TVpointY; tvpz=TVpointZ;
01101 LastMainFp=Nface;
01102 LastMainEp=Nedge;
01103 LastMainVp=Nvert;
01104 vp=0; Vp=MainVp; while(vp < Nvert){
01105 if(Vp->status == SELECTED)Vp->status=INEDITOR;
01106 vp++; Vp++;
01107 }
01108 switch (primitivetype){
01109 case 0:
01110 opx=(long)(PrimStruct.lr*ruler)+lrulerx;
01111 opy=(long)(PrimStruct.fb*ruler)+lrulery;
01112 opz=(long)(PrimStruct.ud*ruler)+lrulerz;
01113 dx=(long)(PrimStruct.width*ruler)*PrimStruct.mw;
01114 dy=(long)(PrimStruct.length*ruler)*PrimStruct.ml;
01115 if(!UpdateVertexHeap(Nvert+4))goto ABRT;
01116 if(!UpdateEdgeHeap(Nedge+5))goto ABRT;
01117 if(!UpdateFaceHeap(Nface+2))goto ABRT;
01118 CreateVertex(); v1=Nvert-1; CreateVertex(); v2=Nvert-1;
01119 CreateVertex(); v3=Nvert-1; CreateVertex(); v4=Nvert-1;
01120 CreateEdge(v1,v2); CreateEdge(v2,v3);
01121 CreateEdge(v3,v4); CreateEdge(v4,v1);
01122 CreateEdge(v1,v3);
01123 CreateFace(v1,v3,v2); CreateFace(v1,v4,v3);
01124 fp=LastMainFp; while(fp < Nface){
01125 for(i=0;i<3;i++)(MainFp+fp)->color[i]=PrimStruct.fc[i];
01126 fp++;
01127 }
01128 if(view == TRITOP){
01129 (MainVp+v1)->xyz[2]=(MainVp+v2)->xyz[2]=
01130 (MainVp+v3)->xyz[2]=(MainVp+v4)->xyz[2]=opz;
01131 (MainVp+v1)->xyz[0]=(MainVp+v4)->xyz[0]=opx;
01132 (MainVp+v2)->xyz[0]=(MainVp+v3)->xyz[0]=opx+dx;
01133 (MainVp+v1)->xyz[1]=(MainVp+v2)->xyz[1]=opy;
01134 (MainVp+v3)->xyz[1]=(MainVp+v4)->xyz[1]=opy+dy;
01135 }
01136 else if(view == TRIFRONT){
01137 (MainVp+v1)->xyz[1]=(MainVp+v2)->xyz[1]=
01138 (MainVp+v3)->xyz[1]=(MainVp+v4)->xyz[1]=opy;
01139 (MainVp+v1)->xyz[0]=(MainVp+v4)->xyz[0]=opx;
01140 (MainVp+v2)->xyz[0]=(MainVp+v3)->xyz[0]=opx+dx;
01141 (MainVp+v1)->xyz[2]=(MainVp+v2)->xyz[2]=opz;
01142 (MainVp+v3)->xyz[2]=(MainVp+v4)->xyz[2]=opz+dy;
01143 }
01144 else if(view == TRIRIGHT){
01145 (MainVp+v1)->xyz[0]=(MainVp+v2)->xyz[0]=
01146 (MainVp+v3)->xyz[0]=(MainVp+v4)->xyz[0]=opx;
01147 (MainVp+v1)->xyz[1]=(MainVp+v4)->xyz[1]=opy;
01148 (MainVp+v2)->xyz[1]=(MainVp+v3)->xyz[1]=opy+dx;
01149 (MainVp+v1)->xyz[2]=(MainVp+v2)->xyz[2]=opz;
01150 (MainVp+v3)->xyz[2]=(MainVp+v4)->xyz[2]=opz+dy;
01151 }
01152 break;
01153 case 1:
01154 opx=(long)(PrimStruct.lr*ruler)+lrulerx;
01155 opy=(long)(PrimStruct.fb*ruler)+lrulery;
01156 opz=(long)(PrimStruct.ud*ruler)+lrulerz;
01157 dx=(long)(PrimStruct.width*ruler)/2;
01158 dy=(long)(PrimStruct.length*ruler)/2;
01159 dz=(long)(PrimStruct.height*ruler)/2;
01160 if(!UpdateVertexHeap(Nvert+8))goto ABRT;
01161 if(!UpdateEdgeHeap(Nedge+18))goto ABRT;
01162 if(!UpdateFaceHeap(Nface+12))goto ABRT;
01163 CreateVertex(); v1=Nvert-1; CreateVertex(); v2=Nvert-1;
01164 CreateVertex(); v3=Nvert-1; CreateVertex(); v4=Nvert-1;
01165 CreateVertex(); v5=Nvert-1; CreateVertex(); v6=Nvert-1;
01166 CreateVertex(); v7=Nvert-1; CreateVertex(); v8=Nvert-1;
01167 CreateEdge(v1,v2); CreateEdge(v2,v3);
01168 CreateEdge(v3,v4); CreateEdge(v4,v1);
01169 CreateEdge(v1,v3);
01170 CreateEdge(v5,v6); CreateEdge(v6,v7);
01171 CreateEdge(v7,v8); CreateEdge(v8,v5);
01172 CreateEdge(v5,v7);
01173 CreateEdge(v1,v5); CreateEdge(v2,v6);
01174 CreateEdge(v3,v7); CreateEdge(v4,v8);
01175 CreateEdge(v1,v6); CreateEdge(v2,v7);
01176 CreateEdge(v3,v8); CreateEdge(v4,v5);
01177 CreateFace(v1,v2,v3); CreateFace(v1,v3,v4);
01178 CreateFace(v5,v7,v6); CreateFace(v5,v8,v7);
01179 CreateFace(v1,v6,v2); CreateFace(v1,v5,v6);
01180 CreateFace(v2,v7,v3); CreateFace(v2,v6,v7);
01181 CreateFace(v3,v8,v4); CreateFace(v3,v7,v8);
01182 CreateFace(v4,v5,v1); CreateFace(v4,v8,v5);
01183 (MainVp+v1)->xyz[2]=(MainVp+v2)->xyz[2]=
01184 (MainVp+v3)->xyz[2]=(MainVp+v4)->xyz[2]=opz+dz;
01185 (MainVp+v1)->xyz[0]=(MainVp+v4)->xyz[0]=opx+dx;
01186 (MainVp+v2)->xyz[0]=(MainVp+v3)->xyz[0]=opx-dx;
01187 (MainVp+v1)->xyz[1]=(MainVp+v2)->xyz[1]=opy+dy;
01188 (MainVp+v3)->xyz[1]=(MainVp+v4)->xyz[1]=opy-dy;
01189 (MainVp+v5)->xyz[2]=(MainVp+v6)->xyz[2]=
01190 (MainVp+v7)->xyz[2]=(MainVp+v8)->xyz[2]=opz-dz;
01191 (MainVp+v5)->xyz[0]=(MainVp+v8)->xyz[0]=opx+dx;
01192 (MainVp+v6)->xyz[0]=(MainVp+v7)->xyz[0]=opx-dx;
01193 (MainVp+v5)->xyz[1]=(MainVp+v6)->xyz[1]=opy+dy;
01194 (MainVp+v7)->xyz[1]=(MainVp+v8)->xyz[1]=opy-dy;
01195 fp=LastMainFp; while(fp < Nface){
01196 for(i=0;i<3;i++)(MainFp+fp)->color[i]=PrimStruct.fc[i];
01197 fp++;
01198 }
01199 break;
01200 case 2:
01201 NpointerX=opx=(long)(PrimStruct.lr*ruler)+lrulerx;
01202 NpointerY=opy=(long)(PrimStruct.fb*ruler)+lrulery;
01203 NpointerZ=opz=(long)(PrimStruct.ud*ruler)+lrulerz;
01204 radius=(long)(PrimStruct.radius*ruler);
01205 AddPolygon(PrimStruct.nsides,radius,view);
01206 break;
01207 case 3:
01208 NpointerX=opx=(long)(PrimStruct.lr*ruler)+lrulerx;
01209 NpointerY=opy=(long)(PrimStruct.fb*ruler)+lrulery;
01210 NpointerZ=opz=(long)(PrimStruct.ud*ruler)+lrulerz;
01211 radius=(long)(PrimStruct.radius*ruler);
01212 height=(long)(PrimStruct.length*ruler)/2;
01213 n=PrimStruct.nsteps;
01214 if (view == TRITOP )NpointerZ -= height;
01215 else if(view == TRIFRONT)NpointerY -= height;
01216 else if(view == TRIRIGHT)NpointerX -= height;
01217 last_face=Nface;
01218 AddPolygon(PrimStruct.nsides,radius,view);
01219 j=height*2/n;
01220 for(i=0;i<n;i++){
01221 CreateAttachedCopy(1);
01222 vp=LastMainVp; while(vp < Nvert){
01223 Vp=(MainVp+vp);
01224 if(Vp->status == SELECTED){
01225 if(view == TRITOP )Vp->xyz[2] = NpointerZ+j*(i+1);
01226 if(view == TRIFRONT)Vp->xyz[1] = NpointerY+j*(i+1);
01227 if(view == TRIRIGHT)Vp->xyz[0] = NpointerX+j*(i+1);
01228 }
01229 vp++;
01230 }
01231 }
01232 n_face_list=0;
01233 fp=LastMainFp; while(fp < Nface){
01234 for(i=0;i<3;i++)(MainFp+fp)->color[i]=PrimStruct.fc[i];
01235 (MainFp+fp)->bSmooth=TRUE;
01236 n_face_list++;
01237 fp++;
01238 }
01239 if(n_face_list > 0 &&
01240 (face_list = (long *)X__Malloc(n_face_list*sizeof(long))) != NULL){
01241 for(j=0,i=last_face;i<Nface;i++,j++)face_list[j]=i;
01242 if(j == n_face_list){
01243 OrientateFaceNormals(face_list[0],n_face_list,face_list);
01244 if(view == TRIFRONT)ReverseFaceOrientation(n_face_list,face_list);
01245 }
01246 X__Free(face_list);
01247 }
01248 break;
01249 case 4:
01250 NpointerX=opx=(long)(PrimStruct.lr*ruler)+lrulerx;
01251 NpointerY=opy=(long)(PrimStruct.fb*ruler)+lrulery;
01252 NpointerZ=opz=(long)(PrimStruct.ud*ruler)+lrulerz;
01253 radius=(long)(PrimStruct.radius*ruler);
01254 AddPolygon(PrimStruct.nsides,radius,view);
01255 if(Nvert <= LastMainVp)break;
01256 AutoFillFace(LastMainVp);
01257 fp=LastMainFp; while(fp < Nface){
01258 for(i=0;i<3;i++)(MainFp+fp)->color[i]=PrimStruct.fc[i];
01259 fp++;
01260 }
01261 break;
01262 case 5:
01263 NpointerX=opx=(long)(PrimStruct.lr*ruler)+lrulerx;
01264 NpointerY=opy=(long)(PrimStruct.fb*ruler)+lrulery;
01265 NpointerZ=opz=(long)(PrimStruct.ud*ruler)+lrulerz;
01266 radius=(long)(PrimStruct.radius*ruler);
01267 height=(long)(PrimStruct.length*ruler)/2;
01268 n=PrimStruct.nsteps;
01269 if (view == TRITOP )NpointerZ -= height;
01270 else if(view == TRIFRONT)NpointerY -= height;
01271 else if(view == TRIRIGHT)NpointerX -= height;
01272 last_face=LastMainFp;
01273 AddPolygon(PrimStruct.nsides,radius,view);
01274 if(Nvert <= LastMainVp)break;
01275
01276 AutoFillFace(LastMainVp);
01277
01278
01279 j=height*2/n;
01280 for(i=0;i<n;i++){
01281 CreateAttachedCopy(1);
01282 vp=LastMainVp; while(vp < Nvert){
01283 Vp=(MainVp+vp);
01284 if(Vp->status == SELECTED){
01285 if(view == TRITOP )Vp->xyz[2] = NpointerZ+j*(i+1);
01286 if(view == TRIFRONT)Vp->xyz[1] = NpointerY+j*(i+1);
01287 if(view == TRIRIGHT)Vp->xyz[0] = NpointerX+j*(i+1);
01288 }
01289 vp++;
01290 }
01291 }
01292 if (view == TRITOP )NpointerZ += height*2;
01293 else if(view == TRIFRONT)NpointerY += height*2;
01294 else if(view == TRIRIGHT)NpointerX += height*2;
01295 AutoFillFace(LastMainVp);
01296 (MainVp+Nvert-1)->status=SELECTED;
01297 NvertSelect++; NvertDeselect--;
01298
01299 n_face_list=0;
01300 fp=LastMainFp; while(fp < Nface){
01301 for(i=0;i<3;i++)(MainFp+fp)->color[i]=PrimStruct.fc[i];
01302 (MainFp+fp)->bSmooth=TRUE;
01303 n_face_list++;
01304 fp++;
01305 }
01306 if(n_face_list > 0 &&
01307 (face_list = (long *)X__Malloc(n_face_list*sizeof(long))) != NULL){
01308 for(j=0,i=last_face;i<Nface;i++,j++)face_list[j]=i;
01309 if(j == n_face_list){
01310 OrientateFaceNormals(face_list[0],n_face_list,face_list);
01311 if(TRIFRONT != view)ReverseFaceOrientation(n_face_list,face_list);
01312 }
01313 X__Free(face_list);
01314 }
01315 break;
01316 case 6:
01317 NpointerX=opx=(long)(PrimStruct.lr*ruler)+lrulerx;
01318 NpointerY=opy=(long)(PrimStruct.fb*ruler)+lrulery;
01319 NpointerZ=opz=(long)(PrimStruct.ud*ruler)+lrulerz;
01320 radius=(long)(PrimStruct.radius*ruler);
01321 height=(long)(PrimStruct.length*ruler)/2;
01322 if (view == TRITOP )NpointerZ -= height;
01323 else if(view == TRIFRONT)NpointerY -= height;
01324 else if(view == TRIRIGHT)NpointerX -= height;
01325 AddPolygon(PrimStruct.nsides,radius,view);
01326 if(Nvert <= LastMainVp)break;
01327 AutoFillFace(LastMainVp);
01328 AutoFillFace(LastMainVp);
01329 Vp=(MainVp+Nvert-1);
01330 if(view == TRITOP )Vp->xyz[2] = NpointerZ+height*2;
01331 if(view == TRIFRONT)Vp->xyz[1] = NpointerY+height*2;
01332 if(view == TRIRIGHT)Vp->xyz[0] = NpointerX+height*2;
01333 Vp->status=SELECTED;
01334 NvertSelect++; NvertDeselect--;
01335 fp=LastMainFp; while(fp < Nface){
01336 for(i=0;i<3;i++)(MainFp+fp)->color[i]=PrimStruct.fc[i];
01337 (MainFp+fp)->bSmooth=TRUE;
01338 fp++;
01339 }
01340 break;
01341 case 7:
01342 NpointerX=opx=(long)(PrimStruct.lr*ruler)+lrulerx;
01343 NpointerY=opy=(long)(PrimStruct.fb*ruler)+lrulery;
01344 NpointerZ=opz=(long)(PrimStruct.ud*ruler)+lrulerz;
01345 radius=(long)(PrimStruct.radius*ruler);
01346 TVsizeZ=TVsizeX=TVsizeY=radius*2;
01347 TVpointX=opx-radius;
01348 TVpointY=opy-radius;
01349 TVpointZ=opz-radius;
01350 if(!UpdateVertexHeap(Nvert+12))goto ABRT;
01351 if(!UpdateEdgeHeap(Nedge+30))goto ABRT;
01352 if(!UpdateFaceHeap(Nface+20))goto ABRT;
01353 for(i=0;i<12;i++){
01354 CreateVertex(); vs[i]=Nvert-1;
01355 if(i < 10)(MainVp+vs[i])->xyz[0]=TVpointX;
01356 }
01357 (MainVp+vs[10])->xyz[2]=TVpointZ;
01358 (MainVp+vs[11])->xyz[2]=TVpointZ+TVsizeZ;
01359 for(i=0;i<5;i++){
01360 (MainVp+vs[i])->xyz[2]=TVpointZ+TVsizeZ/4;
01361 (MainVp+vs[i+5])->xyz[2]=TVpointZ+(TVsizeZ*3)/4;
01362 RotatePointXY((MainVp+vs[i+5])->xyz,i*72);
01363 RotatePointXY((MainVp+vs[i])->xyz,i*72+36);
01364 }
01365 for(i=0;i<4;i++){
01366 CreateEdge(vs[i],vs[i+1]); CreateEdge(vs[i+5],vs[i+6]);
01367 CreateEdge(vs[i],vs[i+5]); CreateEdge(vs[i],vs[i+6]);
01368 CreateEdge(vs[i],vs[10]); CreateEdge(vs[i+5],vs[11]);
01369 }
01370 CreateEdge(vs[4],vs[0]); CreateEdge(vs[9],vs[5]);
01371 CreateEdge(vs[4],vs[5]); CreateEdge(vs[4],vs[9]);
01372 CreateEdge(vs[4],vs[10]); CreateEdge(vs[9],vs[11]);
01373 for(i=0;i<30;i+=3){
01374 CreateFace(vs[fid[i]],vs[fid[i+1]],vs[fid[i+2]]);
01375 }
01376 for(i=0;i<4;i++){
01377 CreateFace(vs[10],vs[i+1],vs[i]);
01378 CreateFace(vs[11],vs[i+5],vs[i+6]);
01379 }
01380 CreateFace(vs[10],vs[0],vs[4]);
01381 CreateFace(vs[11],vs[9],vs[5]);
01382 Explode(0);
01383 if(PrimStruct.faces > 20){
01384 Subdivide(LastMainFp,LastMainEp,0);
01385 Explode(0);
01386 if(PrimStruct.faces > 80){
01387 Subdivide(LastMainFp,LastMainEp,0);
01388 Explode(0);
01389 if(PrimStruct.faces > 320){
01390 Subdivide(LastMainFp,LastMainEp,0);
01391 Explode(0);
01392 }
01393 }
01394 }
01395 fp=LastMainFp; while(fp < Nface){
01396 Fp=(MainFp+fp);
01397 for(i=0;i<3;i++)Fp->color[i]=PrimStruct.fc[i];
01398 if(PrimStruct.smooth)Fp->bSmooth=TRUE;
01399 else Fp->bSmooth=FALSE;
01400 fp++;
01401 }
01402 break;
01403 case 8:
01404 case 9:
01405 NpointerX=opx=(long)(PrimStruct.lr*ruler)+lrulerx;
01406 NpointerY=opy=(long)(PrimStruct.fb*ruler)+lrulery;
01407 NpointerZ=opz=(long)(PrimStruct.ud*ruler)+lrulerz;
01408 radius=(long)(PrimStruct.radius*ruler);
01409 TVsizeZ=TVsizeX=TVsizeY=radius*2;
01410 TVpointX=opx-radius;
01411 TVpointY=opy-radius;
01412 TVpointZ=opz-radius;
01413 if(primitivetype == 8){
01414 if(!MakeLatLongSphere(PrimStruct.nvert,PrimStruct.nhorz,
01415 view))goto ABRT;
01416 }
01417 if(primitivetype == 9){
01418 if(!MakeTorus(PrimStruct.nvert,PrimStruct.nhorz,
01419 PrimStruct.torus_ratio,view))goto ABRT;
01420 }
01421 fp=LastMainFp; while(fp < Nface){
01422 Fp=(MainFp+fp);
01423 for(i=0;i<3;i++)Fp->color[i]=PrimStruct.fc[i];
01424 if(PrimStruct.smooth)Fp->bSmooth=TRUE;
01425 else Fp->bSmooth=FALSE;
01426 fp++;
01427 }
01428 break;
01429 default: break;
01430 }
01431 vp=0; Vp=MainVp; while(vp < LastMainVp){
01432 if(Vp->status == INEDITOR)Vp->status=SELECTED;
01433 vp++; Vp++;
01434 }
01435 vp=LastMainVp; Vp=(MainVp+LastMainVp); while(vp < Nvert){
01436 if(Vp->status == DESELECTED){
01437 Vp->status=SELECTED;
01438 NvertSelect++;
01439 NvertDeselect--;
01440 }
01441 vp++; Vp++;
01442 }
01443 NpointerX=x; NpointerY=y; NpointerZ=z;
01444 TVsizeX=tvx; TVsizeY=tvy; TVsizeZ=tvz;
01445 TVpointX=tvpx; TVpointY=tvpy; TVpointZ=tvpz;
01446 DrawModel();
01447 UpdateCounters();
01448 if(ghwndOpenGLview == NULL)Draw3dView(0,0);
01449 else PostMessage(ghwndOpenGLview,(WM_USER+2),0,0);
01450 return;
01451 ABRT:
01452 vp=0; Vp=MainVp; while(vp < LastMainVp){
01453 if(Vp->status == INEDITOR)Vp->status=SELECTED;
01454 vp++; Vp++;
01455 }
01456 return;
01457 }
01458
01459 void ExecutePrimitivesMenu(HWND hWnd){
01460 long idata[9]={IDBM_MENU1_1,IDBM_MENU1_2,IDBM_MENU1_3,
01461 IDBM_MENU1_4,IDBM_MENU1_5,IDBM_MENU1_6,
01462 IDBM_MENU1_7,IDBM_MENU1_8,IDBM_MENU1_9
01463 };
01464 long icommand[9]={
01465 IDM_PRIMITIVE_QADD_1,
01466 IDM_PRIMITIVE_QADD_2,
01467 IDM_PRIMITIVE_QADD_3,
01468 IDM_PRIMITIVE_QADD_4,
01469 IDM_PRIMITIVE_QADD_5,
01470 IDM_PRIMITIVE_QADD_6,
01471 IDM_PRIMITIVE_QADD_7,
01472 IDM_PRIMITIVE_QADD_8,
01473 IDM_PRIMITIVE_QADD_9
01474 };
01475 int i;
01476 POINT pt;
01477 HMENU hMenu=CreatePopupMenu();
01478 HBITMAP hBitmap[9];
01479 RECT rc;
01480 UINT align=TPM_LEFTALIGN;
01481 GetWindowRect(GetDlgItem(ghwndTools,10),&rc);
01482 if(bToolpannelLeft){pt.x=rc.right; align=TPM_LEFTALIGN; }
01483 else {pt.x=rc.left; align=TPM_RIGHTALIGN;}
01484 pt.y=rc.top;
01485
01486 for(i=0;i<9;i++){
01487 hBitmap[i]=LoadBitmap(ghinst_main,MAKEINTRESOURCE(idata[i]));
01488 AppendMenu(hMenu,MF_ENABLED|MF_BITMAP,icommand[i],(LPCSTR)hBitmap[i]);
01489 if(i == 6)
01490 AppendMenu(hMenu,MF_SEPARATOR,0,NULL);
01491 }
01492 TrackPopupMenu(hMenu,align | TPM_LEFTBUTTON,
01493 pt.x,pt.y,0,hWnd,NULL);
01494 DestroyMenu(hMenu);
01495 for(i=0;i<9;i++){
01496 if(hBitmap[i] != NULL)DeleteObject(hBitmap);
01497 }
01498 InvalidateRect(ghwndTools,NULL,FALSE);
01499 }
01500
01501 void AddSinglePrimitive(long command){
01502 long i;
01503 EDIT_ACTION=YES;
01504 memset(&PrimStruct,0,sizeof(PRIMITIVE));
01505 PrimStruct.nsides=12;
01506 PrimStruct.smooth=1;
01507 PrimStruct.faces=320;
01508 PrimStruct.nsteps=2;
01509 for(i=0;i<3;i++)PrimStruct.fc[i]=FaceColour[i];
01510 UpdatePrimitiveStructure(0,ActiveView,
01511 TVcentreX-max(TVsizeX,TVsizeY)/8,
01512 TVcentreY-max(TVsizeX,TVsizeY)/8,
01513 TVcentreZ-max(TVsizeX,TVsizeY)/8,
01514 TVcentreX+max(TVsizeX,TVsizeY)/8,
01515 TVcentreY+max(TVsizeX,TVsizeY)/8,
01516 TVcentreZ+max(TVsizeX,TVsizeY)/8,
01517 NpointerX,NpointerY,NpointerZ);
01518 switch (command){
01519 case IDM_PRIMITIVE_QADD_1:
01520 BuildPrimitive(1,ActiveView);
01521 break;
01522 case IDM_PRIMITIVE_QADD_2:
01523 BuildPrimitive(7,ActiveView);
01524 break;
01525 case IDM_PRIMITIVE_QADD_3:
01526 BuildPrimitive(0,ActiveView);
01527 break;
01528 case IDM_PRIMITIVE_QADD_4:
01529 BuildPrimitive(5,ActiveView);
01530 break;
01531 case IDM_PRIMITIVE_QADD_5:
01532 BuildPrimitive(6,ActiveView);
01533 break;
01534 case IDM_PRIMITIVE_QADD_6:
01535 BuildPrimitive(2,ActiveView);
01536 break;
01537 case IDM_PRIMITIVE_QADD_7:
01538 BuildPrimitive(3,ActiveView);
01539 break;
01540 default: break;
01541 }
01542 }
01543
01544
01545
01546 void MakeAutoWireFrame(void){
01547 HCURSOR lhcurSave;
01548 vertex *vp,*vf,*V0,*V1;
01549 edge *ep;
01550 int e1[12]={0,1,2,3,4,5,6,7,0,1,2,3};
01551 int e2[12]={1,2,3,0,5,6,7,4,4,5,6,7};
01552 int i,k,ki,ei,flag,kount;
01553 int type=0;
01554 long xmin,ymin,zmin,xmax,ymax,zmax;
01555 if(w_frame.p != NULL || w_frame.e != NULL ||
01556 w_frame.Np > 0 || w_frame.Ne > 0 ){
01557 SendPrgmQuery(IDQ_WIREEXISTS,0);
01558 return;
01559 }
01560 if(Nvert < 1 || Nedge < 1 || MainVp == NULL || MainEp == NULL)return;
01561 EDIT_ACTION=YES;
01562 lhcurSave=SetCursor(ghcurWait);
01563 if(type == 0){
01564 vp=MainVp;
01565 vf=NULL;
01566 for(vp=MainVp,i=0;i<Nvert;i++,vp++)vp->id=0;
01567 kount=0;
01568 while(TRUE){
01569 flag=0;
01570 for(vp=MainVp,i=0;i<Nvert;i++,vp++){
01571 if(vp->id == 0){
01572 vf=vp;
01573 kount++;
01574 goto GOTNEXT;
01575 }
01576 }
01577 goto NOMORE;
01578 GOTNEXT:
01579 vp=vf;
01580 vp->id=kount;
01581 flag=1;
01582 while(flag){
01583 flag=0;
01584 ep=MainEp; for(i=0;i<Nedge;i++){
01585 V0=(MainVp+ep->V[0]);
01586 V1=(MainVp+ep->V[1]);
01587 if(V0->id == kount && V1->id == 0 && V1->status != HIDDEN){
01588 V1->id = kount; flag=1;
01589 }
01590 if(V1->id == kount && V0->id == 0 && V0->status != HIDDEN){
01591 V0->id = kount; flag=1;
01592 }
01593 ep++;
01594 }
01595 }
01596 }
01597 NOMORE:
01598 if(kount > 0 && kount < 100){
01599 if((w_frame.p=(point *)X__Malloc(8*kount*sizeof(point))) == NULL){
01600 SendPrgmQuery(IDQ_NOMEM1,0);
01601 goto XXIT;
01602 }
01603 w_frame.Np=kount*8;
01604 if((w_frame.e=(twoLongs *)X__Malloc(12*kount*sizeof(twoLongs))) == NULL){
01605 if(w_frame.p != NULL)X__Free(w_frame.p);
01606 w_frame.p=NULL;
01607 SendPrgmQuery(IDQ_NOMEM1,0);
01608 goto XXIT;
01609 }
01610 w_frame.Ne=kount*12;
01611 for(k=0;k<kount;k++){
01612 xmax=ymax=zmax = -MAXUNIT;
01613 xmin=ymin=zmin = MAXUNIT;
01614 for(vp=MainVp,i=0;i<Nvert;i++,vp++){
01615 if(vp->id == k+1){
01616 if(vp->xyz[0] > xmax)xmax=vp->xyz[0];
01617 if(vp->xyz[0] < xmin)xmin=vp->xyz[0];
01618 if(vp->xyz[1] > ymax)ymax=vp->xyz[1];
01619 if(vp->xyz[1] < ymin)ymin=vp->xyz[1];
01620 if(vp->xyz[2] > zmax)zmax=vp->xyz[2];
01621 if(vp->xyz[2] < zmin)zmin=vp->xyz[2];
01622 }
01623 }
01624 ki=k*8;
01625 w_frame.p[ki ][0] = xmin;
01626 w_frame.p[ki ][1] = ymin;
01627 w_frame.p[ki ][2] = zmin;
01628 w_frame.p[ki+1][0] = xmax;
01629 w_frame.p[ki+1][1] = ymin;
01630 w_frame.p[ki+1][2] = zmin;
01631 w_frame.p[ki+2][0] = xmax;
01632 w_frame.p[ki+2][1] = ymax;
01633 w_frame.p[ki+2][2] = zmin;
01634 w_frame.p[ki+3][0] = xmin;
01635 w_frame.p[ki+3][1] = ymax;
01636 w_frame.p[ki+3][2] = zmin;
01637 w_frame.p[ki+4][0] = xmin;
01638 w_frame.p[ki+4][1] = ymin;
01639 w_frame.p[ki+4][2] = zmax;
01640 w_frame.p[ki+5][0] = xmax;
01641 w_frame.p[ki+5][1] = ymin;
01642 w_frame.p[ki+5][2] = zmax;
01643 w_frame.p[ki+6][0] = xmax;
01644 w_frame.p[ki+6][1] = ymax;
01645 w_frame.p[ki+6][2] = zmax;
01646 w_frame.p[ki+7][0] = xmin;
01647 w_frame.p[ki+7][1] = ymax;
01648 w_frame.p[ki+7][2] = zmax;
01649 ei=k*12;
01650 for(i=0;i<12;i++){
01651 w_frame.e[ei+i][0] = ki+e1[i];
01652 w_frame.e[ei+i][1] = ki+e2[i];
01653 }
01654 }
01655 }
01656 else SendPrgmQuery(IDQ_WIRETOOBIG,0);
01657 }
01658 XXIT:
01659 SetCursor(lhcurSave);
01660 }
01661
01662 int MakeWireFrame(void){
01663 long vp,ep;
01664 vertex *Vp,*V0,*V1;
01665 edge *Ep;
01666 long i,w_size=0;
01667 if(NvertSelect == 0){
01668 SendPrgmQuery(IDQ_TOOFEWVERTICES,0);
01669 return FAIL;
01670 }
01671 if(NvertSelect > 400){
01672 SendPrgmQuery(IDQ_WIRETOOBIG,0);
01673 return FAIL;
01674 }
01675 ep=0; Ep=MainEp; while(ep < Nedge){
01676 if((MainVp+Ep->V[0])->status == SELECTED &&
01677 (MainVp+Ep->V[1])->status == SELECTED)w_size++;
01678 ep++; Ep++;
01679 }
01680 if(w_size == 0){
01681 SendPrgmQuery(IDQ_TOOFEWVERTICES,0);
01682 return FAIL;
01683 }
01684 if((w_frame.p=(point *)X__Malloc(NvertSelect*sizeof(point))) == NULL){
01685 SendPrgmQuery(IDQ_NOMEM1,0);
01686 return FAIL;
01687 }
01688 EDIT_ACTION=YES;
01689 i=0; vp=0; Vp=MainVp; while(vp < Nvert){
01690 if(Vp->status == SELECTED){
01691 w_frame.p[i][0] = Vp->xyz[0];
01692 w_frame.p[i][1] = Vp->xyz[1];
01693 w_frame.p[i][2] = Vp->xyz[2];
01694 Vp->id=i; i++;
01695 }
01696 vp++; Vp++;
01697 }
01698 if(i != NvertSelect){
01699 if(w_frame.p != NULL)X__Free(w_frame.p);
01700 w_frame.p=NULL;
01701 SendPrgmQuery(IDQ_TOOFEWVERTICES,0);
01702 return FAIL;
01703 }
01704 w_frame.Np=i;
01705 if((w_frame.e=(twoLongs *)X__Malloc(w_size*sizeof(twoLongs))) == NULL){
01706 if(w_frame.p != NULL)X__Free(w_frame.p);
01707 w_frame.p=NULL;
01708 SendPrgmQuery(IDQ_NOMEM1,0);
01709 return FAIL;
01710 }
01711 w_frame.Ne=w_size;
01712 i=0; ep=0; Ep=MainEp; while(ep < Nedge){
01713 V0=(MainVp+Ep->V[0]); V1=(MainVp+Ep->V[1]);
01714 if(V0->status == SELECTED && V1->status == SELECTED){
01715 w_frame.e[i][0] = V0->id;
01716 w_frame.e[i][1] = V1->id;
01717 i++;
01718 }
01719 ep++; Ep++;
01720 }
01721 if(i != w_size){
01722 if(w_frame.p != NULL)X__Free(w_frame.p); w_frame.p=NULL; w_frame.Np=0;
01723 if(w_frame.e != NULL)X__Free(w_frame.e); w_frame.e=NULL; w_frame.Ne=0;
01724 SendPrgmQuery(IDQ_TOOFEWVERTICES,0);
01725 return FAIL;
01726 }
01727 return OK;
01728 }
01729
01730 void ClearWireFrame(void){
01731 long i;
01732 long *vtemp;
01733 if(w_frame.p == NULL || w_frame.e == NULL){
01734 SendPrgmQuery(IDQ_WIRENOEXISTS,0);
01735 return;
01736 }
01737 EDIT_ACTION=YES;
01738 X__Free(w_frame.p); w_frame.p=NULL; w_frame.Np=0;
01739 X__Free(w_frame.e); w_frame.e=NULL; w_frame.Ne=0;
01740 }
01741
01742 void UnMakeWireFrame(void){
01743 long i;
01744 long *vtemp;
01745 if(w_frame.p == NULL || w_frame.e == NULL){
01746 SendPrgmQuery(IDQ_WIRENOEXISTS,0);
01747 return;
01748 }
01749 if((vtemp=(long *)X__Malloc(w_frame.Np*sizeof(long))) == NULL){
01750 return;
01751 }
01752 EDIT_ACTION=YES;
01753 if(!UpdateVertexHeap(Nvert+w_frame.Np)){
01754 SendPrgmQuery(IDQ_NOMEM1,0);
01755 return;
01756 }
01757 if(!UpdateEdgeHeap(Nedge+w_frame.Ne)){
01758 SendPrgmQuery(IDQ_NOMEM1,0);
01759 return;
01760 }
01761 for(i=0;i<w_frame.Np;i++){
01762 CreateVertex();
01763 vtemp[i]=Nvert-1;
01764 (MainVp+Nvert-1)->xyz[0]=w_frame.p[i][0];
01765 (MainVp+Nvert-1)->xyz[1]=w_frame.p[i][1];
01766 (MainVp+Nvert-1)->xyz[2]=w_frame.p[i][2];
01767 }
01768 for(i=0;i<w_frame.Ne;i++)CreateEdge(vtemp[w_frame.e[i][0]],
01769 vtemp[w_frame.e[i][1]]);
01770 X__Free(vtemp);
01771 X__Free(w_frame.p); w_frame.p=NULL; w_frame.Np=0;
01772 X__Free(w_frame.e); w_frame.e=NULL; w_frame.Ne=0;
01773 DrawModel();
01774 UpdateCounters();
01775 }
01776
01777 void Nudge(int command){
01778 vertex *vp;
01779 long i,dx,dy,dz;
01780 int sx,sy,step=1;
01781 if(tool == ROTATOR){
01782 int axis;
01783 double angle;
01784 if (GetAsyncKeyState(VK_SHIFT ) & 0x8000)angle = 5.0;
01785 else angle = 1.0;
01786 if(command == IDM_PAN_LEFT || command == IDM_PAN_RIGHT){
01787 Save_Undo(1);
01788 if(command == IDM_PAN_RIGHT)angle *= -1.0;
01789 ActionRotate(ActiveView,angle,0);
01790 do_NOT_abort=TRUE;
01791 DrawModel();
01792 do_NOT_abort=FALSE;
01793 }
01794 return;
01795 }
01796 dx=NpointerX; dy=NpointerY; dz=NpointerZ;
01797 GetWindowCoords(ActiveView,NpointerX,NpointerY,NpointerZ,&sx,&sy);
01798 if(GetAsyncKeyState(VK_SHIFT ) & 0x8000)step=5;
01799 if(command == IDM_PAN_LEFT) sx -= step;
01800 if(command == IDM_PAN_RIGHT)sx += step;
01801 if(command == IDM_PAN_UP) sy -= step;
01802 if(command == IDM_PAN_DOWN) sy += step;
01803 Draw3dCursor();
01804 GetWorldCoords(ActiveView,&NpointerX,&NpointerY,&NpointerZ,sx,sy);
01805 Draw3dCursor();
01806 if(coords_visible)UpdateRuler(0);
01807 if(tool == GRABBER){
01808 dx=NpointerX-dx; dy=NpointerY-dy; dz=NpointerZ-dz;
01809 vp=MainVp; for(i=0;i<Nvert;i++){
01810 if(vp->status == SELECTED){
01811 vp->xyz[0] += dx;
01812 vp->xyz[1] += dy;
01813 vp->xyz[2] += dz;
01814 }
01815 vp++;
01816 }
01817 RecalibrateAllBezier(); RecalibrateMapLocks();
01818 do_NOT_abort=TRUE;
01819 DrawModel();
01820 do_NOT_abort=FALSE;
01821 }
01822 }
01823
01824 void LoadUtility(char *program, char *class, int message, char *arguments){
01825 BOOL n=FALSE;
01826 int result;
01827 char modulename[255];
01828 HWND hWnd=NULL;
01829 if((class == NULL) || ((hWnd=FindWindow(class,NULL)) == NULL)){
01830 strcpy(modulename,gszHomeDir);strcat(modulename,program);
01831 if(arguments != NULL){strcat(modulename," "); strcat(modulename,arguments);}
01832 result=WinExec(modulename,SW_SHOW);
01833 n=TRUE;
01834 if(result < 32){
01835 return;
01836 }
01837 if(class != NULL)hWnd=FindWindow(class,NULL);
01838 }
01839 if(hWnd != NULL && IsWindow(hWnd)){
01840 SetForegroundWindow(hWnd);
01841 BringWindowToTop(hWnd);
01842 ShowWindow(hWnd,SW_SHOW);
01843 if(n)PostMessage(hWnd,WM_COMMAND,message,0);
01844 }
01845 return;
01846 }
01847
01848 int SelectDirectoryName(char *szfile, char *szdir,
01849 char *szTitle, char *szfilter,
01850 HWND parent){
01851 int i;
01852 OPENFILENAME ofn;
01853 char szFilter[80],szdummy[MAX_FILE];
01854 szdummy[0]='\0';
01855 strcpy(szFilter,szfilter);
01856 i=0; while(szFilter[i] != '\0'){
01857 if(szFilter[i] == '|')szFilter[i]='\0'; i++;
01858 }
01859 memset(&ofn,0,sizeof(OPENFILENAME));
01860 ofn.lStructSize=sizeof(OPENFILENAME);
01861 ofn.hwndOwner=parent;
01862 ofn.lpstrFilter=szFilter;
01863 ofn.nFilterIndex=1;
01864 ofn.lpstrFile=szfile;
01865 ofn.nMaxFile=MAX_FILE;
01866 ofn.lpstrFileTitle=szdummy;
01867 ofn.nMaxFileTitle=MAX_FILE;
01868 ofn.lpstrInitialDir=szdir;
01869 ofn.lpstrTitle=szTitle;
01870 ofn.hInstance=ghinst_main;
01871 ofn.lpfnHook=NULL;
01872 ofn.lpTemplateName="DIRECTORYOPEN";
01873 ofn.Flags=OFN_HIDEREADONLY|OFN_PATHMUSTEXIST|
01874 OFN_ENABLETEMPLATE|OFN_NONETWORKBUTTON|
01875 OFN_NOTESTFILECREATE;
01876 i=(int)(GetSaveFileName(&ofn));
01877 if(i){
01878 strcpy(szdummy,szfile);
01879 *AnsiPrev(szdummy,FileInPath(szdummy)) = '\0';
01880 strcpy(szdir,szdummy);
01881 }
01882 return i;
01883 }