00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 static char *id="@(#) $Id: shclippg.c,v 1.2 2006/08/17 19:28:17 mhender Exp $";
00018
00019 #include <shInternal.h>
00020 #include <math.h>
00021 #include <stdio.h>
00022
00025 #define maxpol 1000
00026
00045 void shclippg(int *n0,float *x0,float *y0,float *z0,float *nrm0,int *ic0,int *n1,float **x1,float **y1,float **z1,float **nrm1,int **ic1)
00046 {
00047
00048
00049
00050 float *x2,*y2,*z2;
00051 float *nrm2;
00052 int *ic2;
00053 int in0,in1;
00054 int m1,m2;
00055 int i,j,ip;
00056 float direc;
00057 float t;
00058 int i0;
00059 int verbose;
00060
00061 verbose=0;
00062
00063 m2=maxpol;
00064 x2=(float*)malloc(m2*sizeof(float));
00065 y2=(float*)malloc(m2*sizeof(float));
00066 z2=(float*)malloc(m2*sizeof(float));
00067 nrm2=(float*)malloc(3*m2*sizeof(float));
00068 ic2=(int*)malloc(m2*sizeof(int));
00069
00070 m1=(*n0)+1;
00071 if(*x1==(float*)NULL)*x1=(float*)malloc(m1*sizeof(float));
00072 if(*y1==(float*)NULL)*y1=(float*)malloc(m1*sizeof(float));
00073 if(*z1==(float*)NULL)*z1=(float*)malloc(m1*sizeof(float));
00074 if(*nrm1==(float*)NULL)*nrm1=(float*)malloc(3*m1*sizeof(float));
00075 if(*ic1==(int*)NULL)*ic1=(int*)malloc(m1*sizeof(int));
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 *n1=0;
00089 (*x1)[*n1]=x0[0];
00090 (*y1)[*n1]=y0[0];
00091 (*z1)[*n1]=z0[0];
00092 (*nrm1)[0+3*(*n1)]=nrm0[0];
00093 (*nrm1)[1+3*(*n1)]=nrm0[1];
00094 (*nrm1)[2+3*(*n1)]=nrm0[2];
00095 (*ic1)[*n1]=ic0[0];
00096 (*n1)++;
00097 for(i=1;i<*n0;i++)
00098 {
00099 if(fabs(x0[i]-x0[i-1])+fabs(y0[i]-y0[i-1])+fabs(z0[i]-z0[i-1])>1.e-6)
00100 {
00101 (*x1)[*n1]=x0[i];
00102 (*y1)[*n1]=y0[i];
00103 (*z1)[*n1]=z0[i];
00104 (*nrm1)[ 3*(*n1)]=nrm0[ 3*i];
00105 (*nrm1)[1+3*(*n1)]=nrm0[1+3*i];
00106 (*nrm1)[2+3*(*n1)]=nrm0[2+3*i];
00107 (*ic1)[(*n1)]=ic0[i];
00108 (*n1)++;
00109 }
00110 }
00111
00112
00113
00114 (*x1)[*n1]=x0[0];
00115 (*y1)[*n1]=y0[0];
00116 (*z1)[*n1]=z0[0];
00117 (*nrm1)[ 3*(*n1)]=nrm0[ 3*0];
00118 (*nrm1)[1+3*(*n1)]=nrm0[1+3*0];
00119 (*nrm1)[2+3*(*n1)]=nrm0[2+3*0];
00120 (*ic1)[(*n1)]=ic0[0];
00121 (*n1)++;
00122
00123
00124
00125
00126
00127 if(sh_nplns==0)
00128 {
00129 free(x2);
00130 free(y2);
00131 free(z2);
00132 free(nrm2);
00133 free(ic2);
00134 return;
00135 }
00136
00137 for(ip=0;ip<sh_nplns;ip++)
00138 {
00139 if(verbose)printf("plane %d is ((x,y,z)-(%f,%f,%f)).(%f,%f,%f)*%d>0\n",ip,sh_plno[ 3*ip],sh_plno[1+3*ip],sh_plno[2+3*ip],sh_plnn[ 3*ip],sh_plnn[1+3*ip],sh_plnn[2+3*ip],sh_ipln[ip]);
00140 in0=0;
00141 i0=0;
00142 for(i=0;i<*n1;i++)
00143 {
00144 if(verbose){printf("vertex %d(%d) (%f,%f,%f) is ",i,*n1,(*x1)[i],(*y1)[i],(*z1)[i]);fflush(stdout);}
00145 direc=sh_plnn[ 3*ip]*((*x1)[i]-sh_plno[ 3*ip])+sh_plnn[1+3*ip]*((*y1)[i]-sh_plno[1+3*ip])+sh_plnn[2+3*ip]*((*z1)[i]-sh_plno[2+3*ip]);
00146 in1=sh_ipln[ip]*direc>0;
00147 if(verbose){if(in1)printf("in\n");else printf("out\n");}
00148 if(!in0)i0=i;
00149 in0=in0||in1;
00150 }
00151 if(verbose)fflush(stdout);
00152 if(!in0)
00153 {
00154 if(verbose){printf("Polygon completely outside\n\n");fflush(stdout);}
00155 *n1=0;
00156 free(x2);
00157 free(y2);
00158 free(z2);
00159 free(nrm2);
00160 free(ic2);
00161 return;
00162 }
00163
00164 if(i0>0)i0--;
00165
00166 if(verbose){printf("Starting at vertex %d\n",i0);fflush(stdout);}
00167 #define JUNK
00168 #ifdef JUNK
00169 j=0;
00170 direc=sh_plnn[ 3*ip]*((*x1)[i0]-sh_plno[ 3*ip])+sh_plnn[1+3*ip]*((*y1)[i0]-sh_plno[1+3*ip])+sh_plnn[2+3*ip]*((*z1)[i0]-sh_plno[2+3*ip]);
00171 in0=sh_ipln[ip]*direc>0;
00172 i=i0;
00173 while(i+1<*n1)
00174 {
00175 if(verbose){printf("Vertex %d(%d) (%f,%f,%f) next is %d (%f,%f,%f)\n",i,*n1,(*x1)[i],(*y1)[i],(*z1)[i],i+1,(*x1)[i+1],(*y1)[i+1],(*z1)[i+1]);fflush(stdout);}
00176 direc=sh_plnn[ 3*ip]*((*x1)[i+1]-sh_plno[ 3*ip])
00177 +sh_plnn[1+3*ip]*((*y1)[i+1]-sh_plno[1+3*ip])
00178 +sh_plnn[2+3*ip]*((*z1)[i+1]-sh_plno[2+3*ip]);
00179 in1=sh_ipln[ip]*direc>0;
00180 if(verbose)
00181 {
00182 if(in0){printf(" %d is in\n",i);fflush(stdout);}
00183 if(!in0){printf(" %d is out\n",i);fflush(stdout);}
00184 if(in1){printf(" %d is in\n",i+1);fflush(stdout);}
00185 if(!in1){printf(" %d is out\n",i+1);fflush(stdout);}
00186 }
00187 if(!in0&&!in1)
00188 {
00189 if(verbose){printf(" !in0&&!in1\n");fflush(stdout);}
00190 in0=in1;
00191 i++;
00192 }else if(in0&&in1)
00193 {
00194 if(verbose){printf(" in0&&in1\n");fflush(stdout);}
00195 in0=in1;
00196 if(j+1>m2)
00197 {
00198 m2+=5;
00199 x2=(float*)realloc((void*)x2,m2*sizeof(float));
00200 y2=(float*)realloc((void*)y2,m2*sizeof(float));
00201 z2=(float*)realloc((void*)z2,m2*sizeof(float));
00202 nrm2=(float*)realloc((void*)nrm2,3*m2*sizeof(float));
00203 ic2=(int*)realloc((void*)ic2,m2*sizeof(int));
00204 }
00205 x2[j]=(*x1)[i];
00206 y2[j]=(*y1)[i];
00207 z2[j]=(*z1)[i];
00208 nrm2[ 3*j]=(*nrm1)[ 3*i];
00209 nrm2[1+3*j]=(*nrm1)[1+3*i];
00210 nrm2[2+3*j]=(*nrm1)[2+3*i];
00211 ic2[j]=(*ic1)[i];
00212 j++;
00213
00214 i++;
00215 }else if(!in0&&in1)
00216 {
00217 if(verbose){printf(" !in0&&in1\n");fflush(stdout);}
00218 t=-( sh_plnn[ 3*ip]*((*x1)[i]-sh_plno[ 3*ip])
00219 +sh_plnn[1+3*ip]*((*y1)[i]-sh_plno[1+3*ip])
00220 +sh_plnn[2+3*ip]*((*z1)[i]-sh_plno[2+3*ip]) )
00221 /( sh_plnn[ 3*ip]*((*x1)[i+1]-(*x1)[i])
00222 +sh_plnn[1+3*ip]*((*y1)[i+1]-(*y1)[i])
00223 +sh_plnn[2+3*ip]*((*z1)[i+1]-(*z1)[i]) );
00224 (*x1)[i]=(*x1)[i]+t*((*x1)[i+1]-(*x1)[i]);
00225 (*y1)[i]=(*y1)[i]+t*((*y1)[i+1]-(*y1)[i]);
00226 (*z1)[i]=(*z1)[i]+t*((*z1)[i+1]-(*z1)[i]);
00227 (*nrm1)[ 3*i]=(*nrm1)[ 3*i]+t*((*nrm1)[ 3*(i+1)]-(*nrm1)[ 3*i]);
00228 (*nrm1)[1+3*i]=(*nrm1)[1+3*i]+t*((*nrm1)[1+3*(i+1)]-(*nrm1)[1+3*i]);
00229 (*nrm1)[2+3*i]=(*nrm1)[2+3*i]+t*((*nrm1)[2+3*(i+1)]-(*nrm1)[2+3*i]);
00230 (*ic1)[i]=-1;
00231 if(j+1>m2)
00232 {
00233 m2+=5;
00234 x2=(float*)realloc((void*)x2,m2*sizeof(float));
00235 y2=(float*)realloc((void*)y2,m2*sizeof(float));
00236 z2=(float*)realloc((void*)z2,m2*sizeof(float));
00237 nrm2=(float*)realloc((void*)nrm2,3*m2*sizeof(float));
00238 ic2=(int*)realloc((void*)ic2,m2*sizeof(int));
00239 }
00240 x2[j]=(*x1)[i];
00241 y2[j]=(*y1)[i];
00242 z2[j]=(*z1)[i];
00243 nrm2[ 3*j]=(*nrm1)[ 3*i];
00244 nrm2[1+3*j]=(*nrm1)[1+3*i];
00245 nrm2[2+3*j]=(*nrm1)[2+3*i];
00246 ic2[j]=(*ic1)[i];
00247 j++;
00248 in0=1;
00249 i++;
00250 }else if(in0&&!in1)
00251 {
00252 if(verbose){printf(" in0&&!in1\n");fflush(stdout);}
00253 t=-( sh_plnn[ 3*ip]*((*x1)[i]-sh_plno[ 3*ip])
00254 +sh_plnn[1+3*ip]*((*y1)[i]-sh_plno[1+3*ip])
00255 +sh_plnn[2+3*ip]*((*z1)[i]-sh_plno[2+3*ip]) )
00256 /( sh_plnn[ 3*ip]*((*x1)[i+1]-(*x1)[i])
00257 +sh_plnn[1+3*ip]*((*y1)[i+1]-(*y1)[i])
00258 +sh_plnn[2+3*ip]*((*z1)[i+1]-(*z1)[i]) );
00259 if(j+2>m2)
00260 {
00261 m2+=5;
00262 x2=(float*)realloc((void*)x2,m2*sizeof(float));
00263 y2=(float*)realloc((void*)y2,m2*sizeof(float));
00264 z2=(float*)realloc((void*)z2,m2*sizeof(float));
00265 nrm2=(float*)realloc((void*)nrm2,3*m2*sizeof(float));
00266 ic2=(int*)realloc((void*)ic2,m2*sizeof(int));
00267 }
00268 x2[j]=(*x1)[i];
00269 y2[j]=(*y1)[i];
00270 z2[j]=(*z1)[i];
00271 nrm2[ 3*j]=(*nrm1)[ 3*i];
00272 nrm2[1+3*j]=(*nrm1)[1+3*i];
00273 nrm2[2+3*j]=(*nrm1)[2+3*i];
00274 ic2[j]=(*ic1)[i];
00275 j++;
00276
00277 (*x1)[i]=(*x1)[i]+t*((*x1)[i+1]-(*x1)[i]);
00278 (*y1)[i]=(*y1)[i]+t*((*y1)[i+1]-(*y1)[i]);
00279 (*z1)[i]=(*z1)[i]+t*((*z1)[i+1]-(*z1)[i]);
00280 (*nrm1)[ 3*i]=(*nrm1)[ 3*i]+t*((*nrm1)[ 3*(i+1)]-(*nrm1)[ 3*i]);
00281 (*nrm1)[1+3*i]=(*nrm1)[1+3*i]+t*((*nrm1)[1+3*(i+1)]-(*nrm1)[1+3*i]);
00282 (*nrm1)[2+3*i]=(*nrm1)[2+3*i]+t*((*nrm1)[2+3*(i+1)]-(*nrm1)[2+3*i]);
00283 (*ic1)[i]=1;
00284
00285 x2[j]=(*x1)[i];
00286 y2[j]=(*y1)[i];
00287 z2[j]=(*z1)[i];
00288 nrm2[ 3*j]=(*nrm1)[ 3*i];
00289 nrm2[1+3*j]=(*nrm1)[1+3*i];
00290 nrm2[2+3*j]=(*nrm1)[2+3*i];
00291 ic2[j]=(*ic1)[i];
00292 j++;
00293
00294 in0=0;
00295 }
00296 }
00297 if(verbose){printf("done plane %d, Caught %d vertices\n",ip,j);fflush(stdout);}
00298
00299
00300
00301 if(j+1>m1)
00302 {
00303 m1=j+3;
00304 *x1=(float*)realloc((void*)(*x1),m1*sizeof(float));
00305 *y1=(float*)realloc((void*)(*y1),m1*sizeof(float));
00306 *z1=(float*)realloc((void*)(*z1),m1*sizeof(float));
00307 *nrm1=(float*)realloc((void*)(*nrm1),3*m1*sizeof(float));
00308 *ic1=(int*)realloc((void*)(*ic1),m1*sizeof(int));
00309 }
00310
00311 for(i=0;i<j;i++)
00312 {
00313 (*x1)[i]=x2[i];
00314 (*y1)[i]=y2[i];
00315 (*z1)[i]=z2[i];
00316 (*nrm1)[ 3*i]=nrm2[ 3*i];
00317 (*nrm1)[1+3*i]=nrm2[1+3*i];
00318 (*nrm1)[2+3*i]=nrm2[2+3*i];
00319 (*ic1)[i]=ic2[i];
00320 }
00321 (*x1)[j]=x2[0];
00322 (*y1)[j]=y2[0];
00323 (*z1)[j]=z2[0];
00324 (*nrm1)[ 3*j]=nrm2[ 3*0];
00325 (*nrm1)[1+3*j]=nrm2[1+3*0];
00326 (*nrm1)[2+3*j]=nrm2[2+3*0];
00327 (*ic1)[j]=ic2[0];
00328 (*n1)=j+1;
00329 #endif
00330 }
00331
00332 if(verbose){printf("Part of Polygon remains unclipped, %d vertices\n\n",j);fflush(stdout);}
00333
00334 free(x2);
00335 free(y2);
00336 free(z2);
00337 free(nrm2);
00338 free(ic2);
00339
00340 return;
00341 }