TOOLS4.C

Go to the documentation of this file.
00001 /* --
00002 OpenFX - Modelling, Animation and Rendering Package
00003 -- */
00004 
00005 /* file TOOLS4.C  4th designer tools file */
00006 
00007 #define MODULE_TOOLS4 1
00008 
00009 #include "design.h"
00010 
00011 typedef struct WORKFACE {
00012   long f;       // id of the actual face
00013   long fa[3];   // id of adjacent faces in the workface list
00014   int  id;
00015   vector n;
00016 } workface;
00017 
00018 typedef struct VTXADJ {
00019   long nf;
00020   long *flist;
00021 } vtxadj;
00022 
00023 static int Nchange,Npieces;
00024 static workface *WF;
00025 
00026 static void xMakeSameOrientation(long last, long id){
00027  face *f;
00028  long i0,i1,i2,l0,l1,l2,a0,a1,a2;
00029  f=(MainFp+WF[last].f); l0=f->V[0]; l1=f->V[1]; l2=f->V[2];
00030  f=(MainFp+WF[id].f);   i0=f->V[0]; i1=f->V[1]; i2=f->V[2];
00031  a0=WF[id].fa[0]; a1=WF[id].fa[1]; a2=WF[id].fa[2];
00032  if((i2 == l2 && i1 == l1) ||
00033     (i2 == l1 && i1 == l0) ||
00034     (i2 == l0 && i1 == l2)){
00035    WF[id].fa[2]=a0; WF[id].fa[0]=a2;
00036    f->V[2]=i1; f->V[1]=i2; Nchange++;
00037    return;
00038  }
00039  if((i0 == l2 && i2 == l1) ||
00040     (i0 == l1 && i2 == l0) ||
00041     (i0 == l0 && i2 == l2)){
00042    WF[id].fa[0]=a1; WF[id].fa[1]=a0;
00043    f->V[0]=i2; f->V[2]=i0; Nchange++;
00044    return;
00045  }
00046  if((i1 == l1 && i0 == l0) ||
00047     (i1 == l2 && i0 == l1) ||
00048     (i1 == l0 && i0 == l2)){
00049    WF[id].fa[1]=a2; WF[id].fa[2]=a1;
00050    f->V[1]=i0; f->V[0]=i1; Nchange++;
00051    return;
00052  }
00053  return;
00054 }
00055 
00056 static void xSetConnectingID(long last,long id){
00057  if(WF[id].id == 1)return;
00058  WF[id].id=1;
00059  if(last >= 0)xMakeSameOrientation(last,id);
00060  last=id;
00061  if(WF[id].fa[0] >= 0)xSetConnectingID(last,WF[id].fa[0]);
00062  if(WF[id].fa[1] >= 0)xSetConnectingID(last,WF[id].fa[1]);
00063  if(WF[id].fa[2] >= 0)xSetConnectingID(last,WF[id].fa[2]);
00064 }
00065 
00066 static void xReorientate(workface *wf, long nf){
00067  long i,id;
00068  WF=wf;
00069  Nchange=0; Npieces=0;
00070  for(i=0;i<nf;i++)wf[i].id = -1;
00071  while(1){ /* keep going until all the bits have been processed */
00072    for(id=0;id<nf;id++){
00073      if(wf[id].id == -1)goto PROCESSIT;
00074    }
00075    break;      /* no bits have been found - so breakout */
00076    PROCESSIT:
00077    xSetConnectingID(-1,id);
00078    Npieces++;
00079  }
00080  return;
00081 }
00082 
00083 static void xFindAdjFaces(workface *wf, long nf){
00084  face *f;
00085  vertex *vp;
00086  vtxadj *vl=NULL;
00087  long c,nvl=0;
00088  long *fl,i,j,k,id,id0,id1,id2,fjd,fkd,n,m,kk,nl[3],ml[3];
00089  vp=MainVp; for(c=0;c<Nvert;c++){
00090    if(vp->id == -1){
00091      vp->id=nvl;
00092      nvl++;
00093    }
00094    else vp->id = -10;
00095    vp++;
00096  }
00097  if((vl=(vtxadj *)X__Malloc(nvl*sizeof(vtxadj))) == NULL)return;
00098  for(i=0;i<nvl;i++){
00099    vl[i].nf=0;
00100    vl[i].flist=NULL;
00101  }
00102  for(i=0;i<nf;i++){ /* make list of work faces attached to each vertex */
00103    f=(MainFp+wf[i].f);
00104    for(j=0;j<3;j++){
00105      id=(MainVp+(f->V[j]))->id;
00106      fl=vl[id].flist;
00107      n=vl[id].nf;
00108      if(fl == NULL){
00109        if((fl=(long *)X__Malloc(sizeof(long))) == NULL)return;
00110      }
00111      else{
00112        if((fl=(long *)X__Realloc(fl,(n+1)*sizeof(long))) == NULL)return;
00113      }
00114      fl[n]=i;
00115      vl[id].flist=fl;
00116      vl[id].nf=n+1;
00117    }
00118  }
00119  for(i=0;i<nf;i++){ /* find faces that are adjacent to workface face i */
00120    f=(MainFp+wf[i].f);
00121    id0=(MainVp+(f->V[0]))->id;
00122    id1=(MainVp+(f->V[1]))->id;
00123    id2=(MainVp+(f->V[2]))->id;
00124    nl[0]=id0; ml[0]=id1;
00125    nl[1]=id1; ml[1]=id2;
00126    nl[2]=id2; ml[2]=id0;
00127    for(kk=0;kk<3;kk++){
00128      wf[i].fa[kk] = -1; 
00129      if((n=vl[nl[kk]].nf) > 0 && (m=vl[ml[kk]].nf) > 0){
00130        for(j=0;j<n;j++){
00131          fjd=vl[nl[kk]].flist[j];
00132          for(k=0;k<m;k++){
00133            fkd=vl[ml[kk]].flist[k];
00134            if(fkd == fjd && fkd != i){
00135              wf[i].fa[kk]=fkd;  
00136              goto ENDF;
00137            }
00138          }
00139        }
00140      }
00141      ENDF:;
00142    }
00143  }
00144  for(i=0;i<nvl;i++){
00145    if(vl[i].flist != NULL)X__Free(vl[i].flist);
00146  }
00147  X__Free(vl);
00148  return;
00149 }
00150 
00151 void OrientateFaceNormals(long sas, long n_work_face, long *face_list){
00152  // sas = same orientation as face ID. If < 0 then make arbitrary.
00153  // then a lsit of Faces
00154  workface *w;
00155  long i,j,v0,v1,v2;
00156  w=NULL;
00157  if(sas >= 0){
00158   v0=(MainFp+sas)->V[0];
00159   v1=(MainFp+sas)->V[1];
00160   v2=(MainFp+sas)->V[2];
00161  }
00162  if((w=(workface *)X__Malloc(n_work_face*(long)sizeof(workface)))
00163        == NULL)return;
00164  for(i=0;i<Nvert;i++)(MainVp+i)->id = 0;
00165  for(j=0;j<n_work_face;j++){
00166    w[j].f=face_list[j];
00167    for(i=0;i<3;i++){
00168      w[j].fa[i] = -1;
00169      (MainVp+(MainFp+w[j].f)->V[i])->id = -1;
00170    }
00171  }
00172  xFindAdjFaces(w,n_work_face);
00173  xReorientate(w,n_work_face);
00174  if(sas >= 0){
00175    if(!IsFOSame(v0,v1,v2,
00176                 (MainFp+face_list[0])->V[0],
00177                 (MainFp+face_list[0])->V[1],
00178                 (MainFp+face_list[0])->V[2]))
00179      ReverseFaceOrientation(n_work_face,face_list);
00180  }
00181  if(w != NULL)X__Free(w);
00182  return;
00183 }
00184 
00185 void ReverseFaceOrientation(long nf, long *face_list){
00186  long i,id;
00187  face *fp;
00188  for(i=0;i<nf;i++){
00189    fp=(MainFp+face_list[i]);
00190    id=fp->V[2];
00191    fp->V[2]=fp->V[0];
00192    fp->V[0]=id;
00193  }
00194  return;
00195 }
00196 
00197 BOOL IsFOSame(long s0, long s1, long s2,
00198                      long v0, long v1, long v2){
00199   vector u,v,n1,n2;
00200   VECSUB((double)(MainVp+s1)->xyz,
00201          (double)(MainVp+s0)->xyz,u)
00202   VECSUB((double)(MainVp+s2)->xyz,
00203          (double)(MainVp+s0)->xyz,v)
00204   CROSS(u,v,n1)
00205   VECSUB((double)(MainVp+v1)->xyz,
00206          (double)(MainVp+v0)->xyz,u)
00207   VECSUB((double)(MainVp+v2)->xyz,
00208          (double)(MainVp+v0)->xyz,v)
00209   CROSS(u,v,n2)
00210   if(DOT(n1,n2) < 0)return FALSE;
00211   return TRUE;
00212 }
00213 
00214 void OrientateSelectedFaces(void){
00215  face *fp;
00216  long i,face_count,*face_list;
00217  face_count=0; face_list=NULL;
00218  if(Nface == 0)return;
00219  for(i=0,fp=MainFp;i<Nface;i++,fp++){
00220    if((MainVp+fp->V[0])->status == SELECTED ||
00221       (MainVp+fp->V[1])->status == SELECTED ||
00222       (MainVp+fp->V[2])->status == SELECTED)face_count++;
00223  }
00224  face_list = (long *)X__Malloc((face_count)*sizeof(long));
00225  if(face_list == NULL)return;
00226  for(i=0,face_count=0,fp=MainFp;i<Nface;i++,fp++){
00227    if((MainVp+fp->V[0])->status == SELECTED ||
00228       (MainVp+fp->V[1])->status == SELECTED ||
00229       (MainVp+fp->V[2])->status == SELECTED){
00230      face_list[face_count]=i;
00231      face_count++;
00232    }
00233  }
00234  if(face_count > 0){
00235    OrientateFaceNormals(0,face_count,face_list);
00236  }
00237  X__Free(face_list);
00238 }
00239 
00240 int TurnIndicatedEdge(void){
00241  int i,sh1,sh2,sv1,sv2,npx,npy,v1,v2,vx,vy,ord1,ord2;
00242  double x,y,z,mu,a,b,c,d,dmin;
00243  edge     *ep,*epid;
00244  vertex   *vp,*vp1,*vp2;
00245  face     *fp,*fp1,*fp2;
00246  if(Nedge == 0 || MainEp == NULL || MainVp == NULL || MainFp == NULL || Nface == 0)return NO;
00247  dmin=(double)TVsizeX*(double)TVsizeX;
00248  epid=NULL;
00249  for(ep=MainEp,i=0;i<Nedge;i++,ep++){
00250    vp1=(MainVp+ep->V[0]); vp2=(MainVp+ep->V[1]);
00251    if(intriview(vp1) || intriview(vp2)){
00252      GetWindowCoords(ActiveView,
00253                      vp1->xyz[0],vp1->xyz[1],vp1->xyz[2],&sh1,&sv1);
00254      GetWindowCoords(ActiveView,
00255                      vp2->xyz[0],vp2->xyz[1],vp2->xyz[2],&sh2,&sv2);
00256      a=(double)(sh2-sh1); b=(double)(sv2-sv1);
00257      GetWindowCoords(ActiveView,
00258                      NpointerX,NpointerY,NpointerZ,&npx,&npy);
00259      if((sh2-sh1) != 0 ||  (sv2-sv1) != 0){
00260        x=(double)npx; y=(double)npy;
00261        mu=(a*(x-(double)sh1) + b*(y-(double)sv1))/(a*a+b*b);
00262        if(mu > 0.0001 && mu < 0.9999){
00263          x=a*mu+(double)sh1; y=b*mu+(double)sv1;
00264          sh1=(short)x; sv1=(short)y;
00265          if(abs(npx-sh1) < 3 && abs(npy-sv1) < 3){/* in 2D range */
00266            a=(double)(vp2->xyz[0]-vp1->xyz[0]);
00267            b=(double)(vp2->xyz[1]-vp1->xyz[1]);
00268            c=(double)(vp2->xyz[2]-vp1->xyz[2]);
00269            mu=(a*((double)NpointerX-(double)(vp1->xyz[0]))
00270               +b*((double)NpointerY-(double)(vp1->xyz[1]))
00271               +c*((double)NpointerZ-(double)(vp1->xyz[2])))/(a*a+b*b+c*c);
00272            x=a*mu+(double)(vp1->xyz[0]);
00273            y=b*mu+(double)(vp1->xyz[1]);
00274            z=c*mu+(double)(vp1->xyz[2]);
00275            d=(x-(double)NpointerX)*(x-(double)NpointerX)
00276             +(y-(double)NpointerY)*(y-(double)NpointerY)
00277             +(z-(double)NpointerZ)*(z-(double)NpointerZ);
00278            if(d < dmin){/* closest in 3D */
00279              dmin=d;
00280              epid=ep;
00281            }
00282          }
00283        }
00284      }
00285    }
00286  }
00287  if(epid == NULL)return NO;
00288  v1=epid->V[0]; v2=epid->V[1];
00289  vp1=(MainVp+v1); vp2=(MainVp+v2);
00290  fp1=fp2=NULL;
00291  for(i=0,fp=MainFp;i<Nface;i++,fp++){
00292    if     (fp->V[0] == v1 && fp->V[1] == v2){
00293      if(fp1 == NULL){fp1=fp; vx=fp->V[2]; ord1=1;} else {fp2=fp; vy=fp->V[2]; ord2=1; goto GOTTWO;}}
00294    else if(fp->V[0] == v2 && fp->V[1] == v1){
00295      if(fp1 == NULL){fp1=fp; vx=fp->V[2]; ord1=2;} else {fp2=fp; vy=fp->V[2]; ord2=2; goto GOTTWO;}}
00296    else if(fp->V[1] == v1 && fp->V[2] == v2){
00297      if(fp1 == NULL){fp1=fp; vx=fp->V[0]; ord1=1;} else {fp2=fp; vy=fp->V[0]; ord2=1; goto GOTTWO;}}
00298    else if(fp->V[1] == v2 && fp->V[2] == v1){
00299      if(fp1 == NULL){fp1=fp; vx=fp->V[0]; ord1=2;} else {fp2=fp; vy=fp->V[0]; ord2=2; goto GOTTWO;}}
00300    else if(fp->V[2] == v1 && fp->V[0] == v2){
00301      if(fp1 == NULL){fp1=fp; vx=fp->V[1]; ord1=1;} else {fp2=fp; vy=fp->V[1]; ord2=1; goto GOTTWO;}}
00302    else if(fp->V[2] == v2 && fp->V[0] == v1){
00303      if(fp1 == NULL){fp1=fp; vx=fp->V[1]; ord1=2;} else {fp2=fp; vy=fp->V[1]; ord2=2; goto GOTTWO;}}
00304  }
00305  return NO;  // one or no adjacent faces to edge
00306  GOTTWO:     // swap 
00307  if(fp1 == NULL || fp2 == NULL)return NO;
00308  //MessageBox(NULL,"Got Faces","Turn Edge",MB_OK);
00309  // swap edges and faces
00310  epid->V[0]=vx; epid->V[1]=vy;
00311  if(ord1 == 1){fp1->V[0]=vx; fp1->V[1]=v1; fp1->V[2]=vy;}
00312  else         {fp1->V[0]=vx; fp1->V[1]=vy; fp1->V[2]=v1;}
00313  if(ord2 == 2){fp2->V[0]=vx; fp2->V[1]=vy; fp2->V[2]=v2;}
00314  else         {fp2->V[0]=vx; fp2->V[1]=v2; fp2->V[2]=vy;}
00315  return YES;
00316 }
00317 
00318 static BOOL IdentifyFaceCommonEdge(face *cf,  face *af,  long *vcf1, long *vcf2, long *vcfx,
00319                                                          long *vaf1, long *vaf2, long *vafx){
00320   if     (cf->V[0] == af->V[0] && cf->V[1] == af->V[2]){
00321     *vcfx=2; *vcf1=0; *vcf2=1;    *vafx=1; *vaf1=0; *vaf2=2;
00322   }
00323   else if(cf->V[0] == af->V[2] && cf->V[1] == af->V[1]){
00324     *vcfx=2; *vcf1=0; *vcf2=1;    *vafx=0; *vaf1=2; *vaf2=1;
00325   }
00326   else if(cf->V[0] == af->V[1] && cf->V[1] == af->V[0]){
00327     *vcfx=2; *vcf1=0; *vcf2=1;    *vafx=2; *vaf1=1; *vaf2=0;
00328   }
00329 
00330   else if(cf->V[2] == af->V[0] && cf->V[0] == af->V[2]){
00331     *vcfx=1; *vcf1=2; *vcf2=0;    *vafx=1; *vaf1=0; *vaf2=2;
00332   }
00333   else if(cf->V[2] == af->V[2] && cf->V[0] == af->V[1]){
00334     *vcfx=1; *vcf1=2; *vcf2=0;    *vafx=0; *vaf1=2; *vaf2=1;
00335   }
00336   else if(cf->V[2] == af->V[1] && cf->V[0] == af->V[0]){
00337     *vcfx=1; *vcf1=2; *vcf2=0;    *vafx=2; *vaf1=1; *vaf2=0;
00338   }
00339 
00340   else if(cf->V[1] == af->V[0] && cf->V[2] == af->V[2]){
00341     *vcfx=0; *vcf1=1; *vcf2=2;    *vafx=1; *vaf1=0; *vaf2=2;
00342   }
00343   else if(cf->V[1] == af->V[2] && cf->V[2] == af->V[1]){
00344     *vcfx=0; *vcf1=1; *vcf2=2;    *vafx=0; *vaf1=2; *vaf2=1;
00345   }
00346   else if(cf->V[1] == af->V[1] && cf->V[2] == af->V[0]){
00347     *vcfx=0; *vcf1=1; *vcf2=2;    *vafx=2; *vaf1=1; *vaf2=0;
00348   }
00349   
00350   // same as first batch but with opposite sign
00351   else if(cf->V[1] == af->V[0] && cf->V[0] == af->V[2]){
00352     *vcfx=2; *vcf1=1; *vcf2=0;    *vafx=1; *vaf1=0; *vaf2=2;
00353   }
00354   else if(cf->V[1] == af->V[2] && cf->V[0] == af->V[1]){
00355     *vcfx=2; *vcf1=1; *vcf2=0;    *vafx=0; *vaf1=2; *vaf2=1;
00356   }
00357   else if(cf->V[1] == af->V[1] && cf->V[0] == af->V[0]){
00358     *vcfx=2; *vcf1=1; *vcf2=0;    *vafx=2; *vaf1=1; *vaf2=0;
00359   }
00360 
00361   else if(cf->V[0] == af->V[0] && cf->V[2] == af->V[2]){
00362     *vcfx=1; *vcf1=0; *vcf2=2;    *vafx=1; *vaf1=0; *vaf2=2;
00363   }
00364   else if(cf->V[0] == af->V[2] && cf->V[2] == af->V[1]){
00365     *vcfx=1; *vcf1=0; *vcf2=2;    *vafx=0; *vaf1=2; *vaf2=1;
00366   }
00367   else if(cf->V[0] == af->V[1] && cf->V[2] == af->V[0]){
00368     *vcfx=1; *vcf1=0; *vcf2=2;    *vafx=2; *vaf1=1; *vaf2=0;
00369   }
00370 
00371   else if(cf->V[2] == af->V[0] && cf->V[1] == af->V[2]){
00372     *vcfx=0; *vcf1=2; *vcf2=1;    *vafx=1; *vaf1=0; *vaf2=2;
00373   }
00374   else if(cf->V[2] == af->V[2] && cf->V[1] == af->V[1]){
00375     *vcfx=0; *vcf1=2; *vcf2=1;    *vafx=0; *vaf1=2; *vaf2=1;
00376   }
00377   else if(cf->V[2] == af->V[1] && cf->V[1] == af->V[0]){
00378     *vcfx=0; *vcf1=2; *vcf2=1;    *vafx=2; *vaf1=1; *vaf2=0;
00379   }
00380   else{ MessageBox(NULL,"Bad ordering",NULL,MB_OK); return FALSE;}
00381   return TRUE;
00382 }
00383  
00384 static void WrapMapExtraVertex(face *cf, face *af){
00385  long vcf1,vcf2,vcfx,vaf1,vaf2,vafx;
00386  double rota,d,cs,ss,a,b,uu,vv,uv,wu,wv;
00387  double x0,y0,x1,y1,x2,y2,x4,y4;
00388  vector u,v,w,ww,c,vn,cfn,afn;
00389  // first identify which vertex in "af" need to be mapped" 
00390  if(!IdentifyFaceCommonEdge(cf,af,&vcf1,&vcf2,&vcfx,&vaf1,&vaf2,&vafx))return;
00391  if(!O_Normalize((MainVp+(cf->V[vcfx]))->xyz,
00392              (MainVp+(cf->V[vcf1]))->xyz,
00393              (MainVp+(cf->V[vcf2]))->xyz,cfn))return; 
00394  if(!O_Normalize((MainVp+(af->V[vafx]))->xyz,
00395              (MainVp+(af->V[vaf2]))->xyz,
00396              (MainVp+(af->V[vaf1]))->xyz,afn))return;
00397  rota=DOT(cfn,afn); 
00398  if(rota > 1.0 || rota < -1.0)rota=0.0;
00399  else if(rota >= 0.0)rota=acos(rota); 
00400  else rota=PI2+acos(rota);
00401  //fprintf(debug,"Rotation %lf   [pt1- %ld %ld]  pt2- %ld %ld]\n",rota*180.0/PI,cf->V[vcf1],af->V[vaf1],cf->V[vcf2],af->V[vaf2]);
00402  VECSUB((double)(MainVp+(cf->V[vcf2]))->xyz,(double)(MainVp+(cf->V[vcf1]))->xyz,v)
00403  VECSUB((double)(MainVp+(cf->V[vcf1]))->xyz,(double)(MainVp+(cf->V[vcfx]))->xyz,u)
00404  VECSUB((double)(MainVp+(af->V[vafx]))->xyz,(double)(MainVp+(af->V[vaf1]))->xyz,w)
00405 
00406  VECCOPY(v,vn); O_normalize(vn); // rotate about edge to unfold
00407  CROSS(vn,w,c)
00408  d=DOT(vn,w);
00409  rota = - rota;
00410  cs=cos(rota); ss=sin(rota);
00411  VECSUM(cs*w,(1.0-cs)*d*vn,ww)
00412  VECSUM(ww,ss*c,w)  // rotated to unfold
00413  
00414  uv=DOT(u,v); uu=DOT(u,u); vv=DOT(v,v); wu=DOT(w,u); wv=DOT(w,v);
00415  d=uu*vv-uv*uv; d=1.0/d;
00416  a=(wu*vv-uv*wv)*d;
00417  b=(wv*uu-uv*wu)*d;
00418  x0=cf->x[vcfx]; y0=cf->y[vcfx];
00419  x1=cf->x[vcf1]; y1=cf->y[vcf1];
00420  x2=cf->x[vcf2]; y2=cf->y[vcf2];
00421  x4=x1+a*(x1-x0)+b*(x2-x1);
00422  y4=y1+a*(y1-y0)+b*(y2-y1);
00423  af->x[vafx]=x4; af->y[vafx]=y4;
00424  af->x[vaf1]=x1; af->y[vaf1]=y1;
00425  af->x[vaf2]=x2; af->y[vaf2]=y2;
00426 }
00427 
00428 static void WrapMapFromAdj(face *f, face *af[2]){
00429   int i,j,k;
00430   for(k=0;k<2;k++)for(i=0;i<3;i++)for(j=0;j<3;j++){
00431     if(f->V[i] == af[k]->V[j]){
00432       f->x[i]=af[k]->x[j];
00433       f->y[i]=af[k]->y[j];
00434     }
00435   }
00436 }
00437 
00438 static void WrapMapFrom(workface *w, long face_count){
00439  BOOL baj;
00440  int i,k,id,done=1,loop=1,ac,odone;
00441  face *cf[3],*af;
00442  while(done < face_count){
00443    odone=done; 
00444    for(k=0;k<face_count;k++){ 
00445      if(w[k].id != 0)continue; // already processed
00446      //fprintf(debug,"Processing face %ld (%ld)\n",w[k].f,k);
00447      af=(MainFp+w[k].f);
00448      for(baj=FALSE,ac=0,i=0;i<3;i++){
00449          if((id=w[k].fa[i]) >= 0)baj=TRUE; // adjacent to something
00450          if(id >= 0 && w[id].id == loop){
00451          //fprintf(debug,"face %ld(%ld)  adjacent to face %ld(%ld) in loop %ld\n",w[k].f,k, w[id].f, id, loop,w[id].id); 
00452          cf[ac]=(MainFp+w[id].f);  ac++;
00453        }
00454      }
00455      if(!baj)done++; // this is not adjacent to anything
00456      else if(ac > 1){  // this face is enclosed by already mapped faces and should have its mapping assigned from the adjacent
00457        WrapMapFromAdj(af,cf);
00458        w[k].id=loop+1;
00459        done++;
00460      }
00461      else if(ac == 1){  // one vertex to be assigned from its neighbours
00462        WrapMapExtraVertex(cf[0],af);
00463        w[k].id=loop+1;
00464        done++;
00465      }
00466    }
00467    loop++;
00468    if(done == odone)break; // we can only have one connected piece as indicated - omit the rest
00469  }
00470 }
00471 
00472 void WrapMapSelectedFaces(void){
00473  face *fp;
00474  long id=-1,i,face_count,*face_list, first_face;
00475  face_count=0; face_list=NULL;
00476  if(Nface == 0)return;
00477  if((id=IdentifyIndicatedFace()) < 0)return;  // identify the face with inside the cursor
00478 //MessageBox(NULL,"Wrap selected faces with map from indicated","Wrap ?",MB_OK);
00479  for(i=0,fp=MainFp;i<Nface;i++,fp++){
00480    if((MainVp+fp->V[0])->status == SELECTED &&
00481       (MainVp+fp->V[1])->status == SELECTED &&
00482       (MainVp+fp->V[2])->status == SELECTED)face_count++;
00483  }
00484  face_list = (long *)X__Malloc((face_count)*sizeof(long));
00485  if(face_list == NULL)return;
00486  for(i=0,face_count=0,fp=MainFp;i<Nface;i++,fp++){
00487    if((MainVp+fp->V[0])->status == SELECTED &&
00488       (MainVp+fp->V[1])->status == SELECTED &&
00489       (MainVp+fp->V[2])->status == SELECTED){
00490      face_list[face_count]=i;
00491      if(i == id)first_face=face_count;
00492      face_count++;
00493    }
00494  }
00495  if(face_count > 0){
00496    workface *w;
00497    long j,f;
00498    w=NULL;
00499    if((w=(workface *)X__Malloc(face_count*(long)sizeof(workface)))
00500          == NULL)return;
00501    for(i=0;i<Nvert;i++)(MainVp+i)->id = 0;
00502    for(j=0;j<face_count;j++){
00503      f=w[j].f=face_list[j];
00504      O_Normalize((MainVp+((MainFp+f)->V[0]))->xyz,
00505                  (MainVp+((MainFp+f)->V[1]))->xyz,
00506                  (MainVp+((MainFp+f)->V[2]))->xyz,w[j].n); // make face normals
00507      for(i=0;i<3;i++){
00508        w[j].fa[i] = -1;
00509        (MainVp+(MainFp+w[j].f)->V[i])->id = -1;
00510      }
00511    }
00512    xFindAdjFaces(w,face_count);
00513    for(j=0;j<face_count;j++)w[j].id=0;
00514    // now start with the first face and process the mapping coordinates of the adjacent faces
00515    w[first_face].id=1;
00516    WrapMapFrom(w,face_count);
00517    if(w != NULL)X__Free(w);
00518  }
00519  X__Free(face_list);
00520 }
00521 
00522 
00523 void SplitSelectedAlongMaterialsMaps(void){
00524  HCURSOR hSave;
00525  vertex *vp,*V0,*V1,*V2;
00526  face   *fp;
00527  long   i,k,ncopy;
00528  long   x,y,z;
00529  long   Nvertex_list,*vertex_list;
00530  if(NvertSelect == 0 || (nMats == 0 && nImaps == 0) || Nface == 0)return;
00531  if(NvertSelect > 32000){
00532    SendPrgmQuery(IDQ_WIRETOOBIG,0);
00533    return;
00534  }
00535  if((vertex_list = (long *)X__Malloc(NvertSelect*sizeof(long))) == NULL)return;
00536  Nvertex_list=NvertSelect;
00537  hSave=SetCursor(ghcurWait);
00538  for(i=0,k=0,vp=MainVp;i<Nvert;i++,vp++){  // make a list of all vertices involved
00539    if(vp->status == SELECTED){vertex_list[k]=i; k++;}
00540  }
00541  for(i=0;i<Nvertex_list;i++){
00542   (MainVp+vertex_list[i])->status=DESELECTED; NvertSelect--; NvertDeselect++;}
00543  
00544  //For all materials make copy of vertices edges and faces by marking them as selected.
00545  if(nMats > 0)for(k=0;k<nMats;k++){
00546    for(i=0,vp=MainVp;i<Nvert;i++,vp++){
00547      vp->id = -1; 
00548      if(vp->status == SELECTED){ vp->status=DESELECTED; NvertSelect--; NvertDeselect++;}
00549    }
00550    for(i=0;i<Nvertex_list;i++)(MainVp+vertex_list[i])->id=1; // Flag this vertex is to be part of the copied object;
00551    for(ncopy=0,fp=MainFp,i=0;i<Nface;i++){
00552      V0=(MainVp+fp->V[0]); V1=(MainVp+fp->V[1]); V2=(MainVp+fp->V[2]);
00553      if(V0->id == 1 &&  V1->id == 1 &&  V2->id == 1 &&   // this vertex is part of the 
00554         fp->material >= 0 && fp->material == k){         // required material
00555        if(V0->status != SELECTED){V0->status=SELECTED; NvertSelect++; NvertDeselect--;}
00556        if(V1->status != SELECTED){V1->status=SELECTED; NvertSelect++; NvertDeselect--;}
00557        if(V2->status != SELECTED){V2->status=SELECTED; NvertSelect++; NvertDeselect--;}
00558        ncopy++;
00559     }       
00560     fp++;
00561   }
00562   if(ncopy > 0)AddCopy(0);
00563  }
00564 
00565  //For all image maps make copy of vertices edges and faces by marking them as selected.
00566  if(nImaps > 0)for(k=0;k<nImaps;k++){
00567    for(i=0,vp=MainVp;i<Nvert;i++,vp++){
00568      vp->id = -1; 
00569      if(vp->status == SELECTED){ vp->status=DESELECTED; NvertSelect--; NvertDeselect++;}
00570    }
00571    for(i=0;i<Nvertex_list;i++)(MainVp+vertex_list[i])->id=1; // Flag this vertex is to be part of the copied object;
00572    for(ncopy=0,fp=MainFp,i=0;i<Nface;i++){
00573      V0=(MainVp+fp->V[0]); V1=(MainVp+fp->V[1]); V2=(MainVp+fp->V[2]);
00574      if(V0->id == 1 &&  V1->id == 1 &&  V2->id == 1 &&   // this vertex is part of the 
00575         fp->imagemap >= 0 && fp->imagemap == k){         // required map
00576        if(V0->status != SELECTED){V0->status=SELECTED; NvertSelect++; NvertDeselect--;}
00577        if(V1->status != SELECTED){V1->status=SELECTED; NvertSelect++; NvertDeselect--;}
00578        if(V2->status != SELECTED){V2->status=SELECTED; NvertSelect++; NvertDeselect--;}
00579        ncopy++;
00580     }       
00581     fp++;
00582   }
00583   if(ncopy > 0)AddCopy(0);
00584  }
00585 
00586  //For all faces without ANY map or material
00587  for(i=0,vp=MainVp;i<Nvert;i++,vp++){
00588    vp->id = -1; 
00589    if(vp->status == SELECTED){ vp->status=DESELECTED; NvertSelect--; NvertDeselect++;}
00590  }
00591  for(i=0;i<Nvertex_list;i++)(MainVp+vertex_list[i])->id=1; // Flag this vertex is to be part of the copied object;
00592  for(ncopy=0,fp=MainFp,i=0;i<Nface;i++){
00593    V0=(MainVp+fp->V[0]); V1=(MainVp+fp->V[1]); V2=(MainVp+fp->V[2]);
00594    if(V0->id == 1 &&  V1->id == 1 &&  V2->id == 1 &&  // this vertex has no map
00595       fp->imagemap < 0 && fp->material < 0){          // or material
00596        if(V0->status != SELECTED){V0->status=SELECTED; NvertSelect++; NvertDeselect--;}
00597        if(V1->status != SELECTED){V1->status=SELECTED; NvertSelect++; NvertDeselect--;}
00598        if(V2->status != SELECTED){V2->status=SELECTED; NvertSelect++; NvertDeselect--;}
00599        ncopy++;
00600     }       
00601     fp++;
00602  }
00603  if(ncopy > 0)AddCopy(0);
00604 
00605  // reset the selection status to the original and remove the original vertices 
00606  for(i=0,vp=MainVp;i<Nvert;i++,vp++){
00607    vp->id = -1; 
00608    if(vp->status == SELECTED){ vp->status=DESELECTED; NvertSelect--; NvertDeselect++;}
00609  }
00610  for(i=0;i<Nvertex_list;i++){
00611    (MainVp+vertex_list[i])->status=SELECTED;
00612    NvertSelect++; NvertDeselect--;
00613  }
00614  EraseVertex(YES); 
00615  X__Free(vertex_list);
00616  SetCursor(hSave);
00617 }
00618 
00619 void GrowSelectedAlongNormal(void){ // expand along the normal vector for each vertex
00620  HCURSOR hSave;
00621  vertex *vp,*V0,*V1,*V2;
00622  face   *fp;
00623  BOOL   bGo=FALSE;
00624  long   i,k;
00625  long   x,y,z;
00626  long   Nvertex_list;
00627  double grow_factor=1.0; // in units of ruler
00628  struct vector_list {vector vn; vertex * vp; long c;} *vertex_list;
00629  vector nv,a,b;
00630  if(NvertSelect < 3)return;
00631  if(Read1Real("Grow By","Factor (Current Units)",&grow_factor,-100.0,100.0,ghwnd_main) == FAIL)return;
00632  if((vertex_list = (struct vector_list *)X__Malloc(NvertSelect*sizeof(struct vector_list))) == NULL)return;
00633  Nvertex_list=NvertSelect;
00634  Save_Undo(1);
00635  grow_factor *= ruler;  // scale to ruler
00636  hSave=SetCursor(ghcurWait);
00637  for(i=0,k=0,vp=MainVp;i<Nvert;i++,vp++){  // make a list of all vertices involved
00638    if(vp->status == SELECTED){
00639      vp->id=k;  // vertex identifier to vertex_list
00640      vertex_list[k].c=0; 
00641      vertex_list[k].vp=vp; 
00642      vertex_list[k].vn[0]=vertex_list[k].vn[1]=vertex_list[k].vn[2]=0.0;
00643      k++;
00644    }
00645  }
00646  for(fp=MainFp,i=0;i<Nface;i++,fp++){  // get the vertex average normals of all faces connected to vertex
00647    V0=(MainVp+fp->V[0]); V1=(MainVp+fp->V[1]); V2=(MainVp+fp->V[2]);
00648    if(V0->status == SELECTED && V0->status == SELECTED && V0->status == SELECTED){
00649      VECSUB((double)V1->xyz,(double)V0->xyz,a)
00650      VECSUB((double)V2->xyz,(double)V0->xyz,b)
00651      CROSS(a,b,nv)
00652      if(O_normalize(nv) == OK){
00653        k=V0->id; VECSUM(vertex_list[k].vn,nv,vertex_list[k].vn) vertex_list[k].c += 1;  
00654        k=V1->id; VECSUM(vertex_list[k].vn,nv,vertex_list[k].vn) vertex_list[k].c += 1;  
00655        k=V2->id; VECSUM(vertex_list[k].vn,nv,vertex_list[k].vn) vertex_list[k].c += 1;  
00656        bGo=TRUE;
00657      }
00658    }  
00659  }
00660  if(bGo){
00661    for(i=0;i<Nvertex_list;i++){
00662      if(vertex_list[i].c > 0){ // scale normals
00663        VECSCALE(1.0/(double)vertex_list[i].c,vertex_list[i].vn,vertex_list[i].vn)
00664      }
00665      else{
00666        vertex_list[i].vn[0]=vertex_list[i].vn[1]=vertex_list[i].vn[2]=0.0;
00667      }
00668    }
00669    for(i=0;i<Nvertex_list;i++)if(vertex_list[i].c > 0){ // apply
00670      vp=vertex_list[i].vp;
00671      VECSUM(vp->xyz,grow_factor*vertex_list[i].vn,vp->xyz)   
00672    }
00673  }
00674  X__Free(vertex_list);
00675  SetCursor(hSave);
00676 }

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