00001
00002
00003
00004
00005
00006
00007 #define MODULE_TOOLS4 1
00008
00009 #include "design.h"
00010
00011 typedef struct WORKFACE {
00012 long f;
00013 long fa[3];
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){
00072 for(id=0;id<nf;id++){
00073 if(wf[id].id == -1)goto PROCESSIT;
00074 }
00075 break;
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++){
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++){
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
00153
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){
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){
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;
00306 GOTTWO:
00307 if(fp1 == NULL || fp2 == NULL)return NO;
00308
00309
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
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
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
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);
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)
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;
00446
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;
00450 if(id >= 0 && w[id].id == loop){
00451
00452 cf[ac]=(MainFp+w[id].f); ac++;
00453 }
00454 }
00455 if(!baj)done++;
00456 else if(ac > 1){
00457 WrapMapFromAdj(af,cf);
00458 w[k].id=loop+1;
00459 done++;
00460 }
00461 else if(ac == 1){
00462 WrapMapExtraVertex(cf[0],af);
00463 w[k].id=loop+1;
00464 done++;
00465 }
00466 }
00467 loop++;
00468 if(done == odone)break;
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;
00478
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);
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
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++){
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
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;
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 &&
00554 fp->material >= 0 && fp->material == k){
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
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;
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 &&
00575 fp->imagemap >= 0 && fp->imagemap == k){
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
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;
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 &&
00595 fp->imagemap < 0 && fp->material < 0){
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
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){
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;
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;
00636 hSave=SetCursor(ghcurWait);
00637 for(i=0,k=0,vp=MainVp;i<Nvert;i++,vp++){
00638 if(vp->status == SELECTED){
00639 vp->id=k;
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++){
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){
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){
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 }