📄 volume_division.br
字号:
p->x=0.5f;p->z=1.0f;p->y=1.0f;
break;
case 6:
p->x=1.0f;p->z=1.0f;p->y=0.5f;
break;
case 7:
p->x=0.5f;p->z=1.0f;p->y=0;
break;
case 8:
p->x=p->y=0; p->z=0.5f;
break;
case 9:
p->x=0;p->y=1.0f;p->z=0.5f;
break;
case 10:
p->x=1.0f;p->y=1.0f;p->z=0.5f;
break;
case 11:
p->x=1.0f;p->y=0;p->z=0.5f;
break;
}
}
}
}
return 0;
}
kernel void smoothTriangles (out float3 trianglesA<>, float4 indices1<>, float4 verticesgather[][], float3 volumeTriangles[][], float curgather[][], float nextgather[][]) { float isovalue=.39; float onehalf=.5; float zero=0; float five=5; float2 mod3 = {round(fmod((indexof trianglesA).x,3.0f)),0}; float2 whichVolumeTriangle; float4 indices = (indices1<4096&&indices1>=0)?indices1:zero.xxxx; if (mod3.x+.5>3) mod3.x=0.0f; whichVolumeTriangle = indices.zw+mod3; { float3 configinf = volumeTriangles[whichVolumeTriangle]; float3 config = configinf<five.xxx?configinf:zero.xxx; float4 vertices = verticesgather[indices.xy]; float low,high; float3 ishalf,tmp; ishalf=(float3)config==onehalf; if (ishalf.z) { float2 lhGather = vertices.xy+config.xy; low = curgather[lhGather]; high = nextgather[lhGather]; }else { float2 lowGather,highGather; if (ishalf.x) { lowGather=float2(vertices.x,vertices.y+config.y); highGather=float2(vertices.x+1.0f,vertices.y+config.y); } else { lowGather=float2(vertices.x+config.x,vertices.y); highGather=float2(vertices.x+config.x,vertices.y+1.0f); } if (configinf.z==0) { low = curgather[lowGather]; high = curgather[highGather]; }else { low = nextgather[lowGather]; high= nextgather[highGather]; } } tmp = (isovalue-low)/(high-low); config=ishalf?tmp:configinf; trianglesA=vertices.xyz+config; }}
/**compute the volume triangles only once and cache it.
*/
Triangle* getVolumeTriangles () {
static Triangle tri[256];
static char eval =volumeTriangles(tri);
return tri;
}
/** Because brook doesn't allow casts in initializers
*/
float tof (int a) {
return (float)a;
}
/** Because brook doesn't allow casts in initializers
*/
int toi (float a) {
return (int)a;
}
/** int main (int argc, char ** argv)
* usage
* ./volume_division [-nofilter] [-noamplify] <width>
* runs the isosurface on a sphere generated into texture coordinates
* ./volume_division [-nofilter] [-noamplify] <filename.ppm>
* runs the isosurface on a modified ppm 3d... may not be 100% valid
* ./volume_division [-nofilter] [-noamplify] <width_height> <depth>
* runs the isosurface on a 3d synthetic dataset that avoids texture reads
* The -nofilter option generates exactly 1 lookup index per voxel
* without said option a lookup is only generated when the voxel will have
* at least 1 triangle in it
* The -noamplify option generates exactly 5 triangles per lookup index given
* without said option the number of triangles outputted is the minumim for
* the given voxel
*/
int main (int argc, char ** argv) {
int i;
float3 volumeTriangles<256,15>;
struct ppm dat;
float * slice=0;
char generatedData=0;
for (i=0;i<argc;++i) {
char match=0;
int j;
if (strcmp(argv[i],"-nofilter")==0) {
match=1;
use_vout_filter=0;//turn off filtering
}else if (strcmp(argv[i],"-noamplify")==0) {
match=1;
use_vout_amplify=0;//turn off amplification
}else if (strcmp(argv[i],"-filter")==0) {
match=1;
use_vout_filter=1;//deprecated
}else if (strcmp(argv[i],"-amplify")==0) {
match=1;
use_vout_amplify=1;//deprecated
}
if (match) {
for (j=i+1;j<argc;++j) argv[j-1]=argv[j];
argc--;
i--;
}
}
if (argc<2) {
fprintf (stderr,"usage\n"
" %s [-nofilter] [-noamplify] <width>\n"
" runs the isosurface on a sphere generated into texture coordinates\n"
" %s [-nofilter] [-noamplify] <filename.ppm>\n"
" runs the isosurface on a modified ppm 3d... may not be 100% valid\n"
" %s [-nofilter] [-noamplify] <width_height> <depth>\n"
" runs the isosurface on a 3d synthetic dataset that avoids texture reads\n"
" The -nofilter option generates exactly 1 lookup index per voxel\n"
" without said option a lookup is only generated when the voxel will have\n"
" at least 1 triangle in it\n"
" The -noamplify option generates exactly 5 triangles per lookup index given\n"
" without said option the number of triangles outputted is the minumim for \n"
" the given voxel\n",argv[0],argv[0],argv[0]);
exit (1);
}
// read in volume triangle lookups
streamRead(volumeTriangles,getVolumeTriangles());
if (argc==2)//use texture memory
{
if (atoi(argv[1])==0) {
dat = openPPM (argv[1]);
if (!dat.fp)
exit(1);
}else {
dat = randomPPM(atoi(argv[1]),atoi(argv[1]),atoi(argv[1]));
}
slice = mallocSlice(dat);
}else {//avoid texture memory and use synthetic lookups
int width=atoi (argv[1]);
int depth=atoi (argv[2]);
int height;
generatedData=1;
if (argc>3)
height=atoi (argv[3]);
else
height=width;
dat = randomPPM(width,height,depth);
}
// now we begin the actual algorithm
{
unsigned int i;
// which volumetric slice is this run going to produce
float2 sliceZ;
// what is the current texutre
float cur<(dat.height),(dat.width)>;
// what is the next texture
float next<(dat.height),(dat.width)>;
// What vertices are we going to spit out
// since the vout code does address translation fill in a good guess
// for the width of the output, but set the height to 1 (was 0)
float4 v<(dat.height),(dat.width)>;
// this iterator tracks the center of the block we're working with
iter float2 center <(dat.height),(dat.width)>
= iter (float2(0.0f,0.0f),
float2(tof(dat.width),
tof(dat.height)));
// this iterator tracks exactly 1 pixel higher in our current or next
// 2d slice
iter float2 up <(dat.height),(dat.width)>
= iter (float2(0.0f,1.0f),
float2(0.0f+tof(dat.width),
1.0f+tof(dat.height)));
// This iterator tracks +1 in x for the current or next 2d slice
iter float2 upforward <(dat.height),(dat.width)>
= iter (float2(1.0f,1.0f),
float2(1.0f+tof(dat.width),
1.0f+tof(dat.height)));
// This iterator tracks +1 in both x & y for the current or next slice
iter float2 forward <(dat.height),(dat.width)>
= iter (float2(1.0f,0.0f),
float2(1.0f+tof(dat.width),
tof(dat.height)));
if (dat.width>512) {// we don't have so much memory.
printf("Exceeded 512 wide texture bounds %d\n",dat.width);
return 1;
}
if (!generatedData) {
// if we aren't dealing with synthetic data, read the first slice
readPPM3dSlice(dat,0,slice);
streamRead(next,slice);
}
// setup the current and next slice Z coordinates
sliceZ.x=0.0f;sliceZ.y=1.0f;
for (i=0;i<dat.depth-1;++i) {//loop through z values
if (!generatedData) {
// read a new slice for the 'next' category
readPPM3dSlice(dat,i+1,slice);
// swap the old with the new
streamSwap(cur,next);
if (i!=dat.depth-1) {
// if we are not at the end, then read one more
streamRead(next,slice);
}
use_vout_filter?
/// only output triangle lookup indices and centers
/// when those indices are not 0 or 255 (empty)
processSlice(cur,
i!=dat.depth-1?next:cur,
v,
center,
up,
forward,
upforward,
sliceZ):
/// produce exactly the number of lookup indices as textures
processSliceNoCompact(cur,
i!=dat.depth-1?next:cur,
v,
center,
up,
forward,
upforward,
sliceZ);
}else {
use_vout_filter?
// use synthetic data, don't compact results
processSyntheticSlice(v,center,upforward,sliceZ):
// use synthetic data, compact results
processSyntheticSliceNoCompact(v,center,upforward,sliceZ);
}
if (streamSize(v).y){
if (use_vout_amplify) {
// multiply our width by 4x since we could output up to 4x
// of our original values
iter float2 newsize <((toi(streamSize(v).y)*5)),
(toi(streamSize(v).x))> =
iter(float2(0,0),float2(streamSize(v).x,
streamSize(v).y*5.0f));
// our first triangle lookups are going to be exactly 3x as big
// float3 trianglesFirst<(toi(streamSize(v).y)),
// (toi(streamSize(v).x)*3)>;
// we know the width of the triangles (i.e. for the address
// calc) will be 4x as big...we have no idea how many 3x
// vout[3] outputs there will be (0 or 3 for each tri)
float4 triangles <1,(toi(streamSize(v).x))>; // process all the first triangles
//processFirstTriangles(trianglesFirst,v,volumeTriangles); // process the rest
processTriangles(triangles, v, volumeTriangles, newsize); //write it to the same place in memory
if (streamSize(triangles).y&&streamSize(triangles).x) { float3 outputTriangles<toi(streamSize(triangles).y),(toi(streamSize(triangles).x)*3)>; smoothTriangles(outputTriangles, triangles, v, volumeTriangles, cur, i!=dat.depth-1?next:cur); fprintf (stderr,"Size %f %f\n",streamSize(outputTriangles).x, streamSize(outputTriangles).y); streamWrite(outputTriangles, consolidateVertices(dat,streamSize(outputTriangles))); } //streamWrite(trianglesFirst, //consolidateVertices(dat,streamSize(trianglesFirst))); }else { // each triangle stream will be 3x bigger than the volume
float3 trianglesA<(toi(streamSize(v).y)*5),
(toi(streamSize(v).x)*3)>;
/* float3 trianglesB<(toi(streamSize(v).y)),
(toi(streamSize(v).x)*3)>;
float3 trianglesC<(toi(streamSize(v).y)),
(toi(streamSize(v).x)*3)>;
float3 trianglesD<(toi(streamSize(v).y)),
(toi(streamSize(v).x)*3)>;
float3 trianglesE<(toi(streamSize(v).y)),
(toi(streamSize(v).x)*3)>;
*/ // output exactly 5 vertices for each input
processTrianglesNoCompactOneOut(trianglesA,
/* trianglesB,
trianglesC,
trianglesD,
trianglesE,
*/ v,
volumeTriangles, cur,
i!=dat.depth-1?next:cur
);
// write them all into mem
streamWrite(trianglesA,
consolidateVertices(dat,streamSize(trianglesA)));
/* streamWrite(trianglesB,
consolidateVertices(dat,streamSize(trianglesB)));
streamWrite(trianglesC,
consolidateVertices(dat,streamSize(trianglesC)));
streamWrite(trianglesD,
consolidateVertices(dat,streamSize(trianglesD)));
streamWrite(trianglesE,
consolidateVertices(dat,streamSize(trianglesE)));
*/ // streamPrint(trianglesA,1);
// streamPrint(trianglesB,1);
// streamPrint(trianglesC,1);
// streamPrint(trianglesD,1);
}
}
// increment the z
sliceZ.x++;sliceZ.y++;
}
}
free(slice);
//write the mesh to stdout
printVolume(dat);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -