00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "VolSlicer.h"
00025 #include <iostream>
00026
00027 using namespace gutz;
00028 using namespace std;
00029
00030
00031
00032
00033
00034 void VolSlicer::slice(mat4f mv,
00035 VolytopeSP vt,
00036 VolSamplesSP vs,
00037 vec3f axis)
00038 {
00039
00040 arrayw1v3f vo = vt->getVerts();
00041 arrayw1v3f tx = vt->getTcoords();
00042 arrayo1v3f rv(vo.size(),vec3f(0));
00043
00044 axis.normalize();
00045
00046 float maxval = -1000000000;
00047 float minval = +1000000000;
00048
00049
00050 mat4f mvinv(mv.inv());
00051
00052 vec3f sn(mvinv.tdir(axis));
00053 sn.normalize();
00054
00055
00056 vec3f eref(-axis*1000);
00057
00058
00059 int vnear,vfar;
00060
00061
00062 for(int i=0; i<vo.size(); ++i)
00063 {
00064 rv[i] = mv.tpoint(vo[i]);
00065 float dfr = (rv[i] - eref).norm();
00066 if(maxval < dfr)
00067 {
00068 maxval = dfr;
00069 vfar = i;
00070 }
00071 if(minval > dfr)
00072 {
00073 minval = dfr;
00074 vnear = i;
00075 }
00076 }
00077
00078 if( (vnear == -1) || (vfar == -1) )
00079 {
00080 cerr << "VolSlicer::slice, invalid volume coordinates, check transforms that "
00081 << " generate the model view matrix!! " << endl;
00082 return;
00083 }
00084
00085
00086 vec3f mref = -sn * 1000;
00087
00088
00089 vec3f vec2near = (vo[vnear] - mref).dot(sn) * sn;
00090 float sts = float((int)(vec2near.norm()/_sampleSpace));
00091 vec3f nearPoint = sts*_sampleSpace * sn + mref;
00092
00093
00094 vec3f vec2far = (vo[vfar] - mref).dot(sn) * sn;
00095 float stf = float((int)(vec2far.norm()/_sampleSpace)+1);
00096 vec3f farPoint = stf*_sampleSpace * sn + mref;
00097
00098
00099 float dist = (nearPoint - farPoint).norm();
00100
00101
00102 int samples = (int)(dist / _sampleSpace) + 1;
00103
00104
00105
00106
00107 vec3f delta = sn*_sampleSpace;
00108
00109
00110 vec3f sp = nearPoint;
00111
00112
00113
00114
00115
00116 arrayw1v2i edg = vt->getEdges();
00117
00118 arrayo1v3f veye(edg.size(),vec3f(0));
00119
00120 arrayw1v3f vout = vs->getVertAttrib()->getArray();
00121 arrayw1v4f tout = vs->getTCoordAttrib()->getArray();
00122 arrayw1v3ui iout = vs->getIdxAttrib()->getArray();
00123 arrayw1v2ui pout = vs->getRangeAttrib()->getArray();
00124
00125 int vStart = 0;
00126 int iStart = 0;
00127
00128
00129
00130
00131 for(int i = 0 ; i < samples; ++i)
00132 {
00133
00134 sp += delta;
00135
00136 int edges = 0;
00137
00138
00139
00140
00141 for(int ne=0; ne < edg.size(); ++ne)
00142 {
00143 int v0 = edg[ne].v0;
00144 int v1 = edg[ne].v1;
00145 edges += intersect(vo[v0], vo[v1], tx[v0], tx[v1], rv[v0], rv[v1], sp, sn,
00146 vout[vStart+edges], tout[vStart+edges], veye[edges]);
00147 }
00148
00149
00150
00151
00152 arrayo1i order(edges,0);
00153
00154 vec3f ecen(0,0,0);
00155 vec3f mcen(0,0,0);
00156 vec3f tcen(0,0,0);
00157
00158 for( int j=0; j<edges; j++)
00159 {
00160 order[j] = j;
00161 ecen += veye[j];
00162 mcen += vout[vStart+j];
00163 tcen += tout[vStart+j];
00164 }
00165 ecen *= 1.0f/(float)edges;
00166 mcen *= 1.0f/(float)edges;
00167 tcen *= 1.0f/(float)edges;
00168
00169 for(int vi=0; vi<edges-1; vi++)
00170 {
00171 float theta = -10;
00172 int next = vi;
00173 for ( int k= vi; k<edges; k++)
00174 {
00175
00176 vec3f dv(veye[order[k]] - ecen);
00177 if( (dv.x == ecen.x) && (dv.y == ecen.y))
00178 {
00179 next = k;
00180
00181 break;
00182 }
00183
00184
00185 float tt = (dv.y)/(mm_abs(dv.x) + mm_abs(dv.y));
00186
00187 if( dv.x < 0.0f )
00188 {
00189 tt = (float)(2.0f - tt);
00190 }
00191 else if( dv.y < 0.0f )
00192 {
00193 tt = (float)(4.0f + tt);
00194 }
00195
00196 if( theta < tt )
00197 {
00198 next = k;
00199 theta = tt;
00200 }
00201 }
00202
00203
00204
00205
00206 int tmp = order[vi];
00207 order[vi] = order[next];
00208 order[next] = tmp;
00209 }
00210
00211
00212
00213
00214 vout[vStart+edges] = mcen;
00215 tout[vStart+edges] = tcen;
00216
00217
00218 for(int tri = 0; tri < edges; ++tri)
00219 {
00220
00221
00222
00223
00224 iout[iStart + tri].z = vStart + order[tri];
00225 iout[iStart + tri].x = vStart + order[((tri + 1) % edges)];
00226 iout[iStart + tri].y = vStart + edges;
00227 }
00228
00229 pout[i].v0 = iStart;
00230 pout[i].v1 = iStart + edges;
00231
00232 vStart += edges + 1;
00233 iStart += edges;
00234
00235 }
00236
00237
00238
00239
00240 vs->getVertAttrib()->setSize(vStart);
00241 vs->getTCoordAttrib()->setSize(vStart);
00242 vs->getIdxAttrib()->setSize(iStart);
00243 vs->getRangeAttrib()->setSize(samples);
00244
00245 }
00246
00247
00248
00249
00250 int VolSlicer::intersect(
00251 const vec3f &m0, const vec3f &m1,
00252 const vec3f &t0, const vec3f &t1,
00253 const vec3f &e0, const vec3f &e1,
00254 const vec3f &sp, const vec3f &sn,
00255 vec3f &pnew, vec4f &tnew, vec3f &vnew)
00256 {
00257 float t = sn.dot(sp - m0) / sn.dot(m1 - m0);
00258
00259
00260
00261
00262 if( (t>=0) && (t<=1) )
00263 {
00264 pnew = m0 + t*(m1 - m0);
00265 tnew = t0 + t*(t1 - t0);
00266 vnew = e0 + t*(e1 - e0);
00267 return 1;
00268 }
00269 return 0;
00270 }