⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 volume_division.br

📁 用于GPU通用计算的编程语言BrookGPU 0.4
💻 BR
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>
#include <stdlib.h>
#include "ppm3d.h"
#include "volume_division.h"
char use_vout_filter=1;
char use_vout_amplify=1;

/**This kernel tests if the data provided is above the cutoff of zero
 * If it is, it returns the single bit passed into the index (ex 1,2,4,...,128)
 */
kernel float test(float vol<>,float index<>){
  return (vol>.39)?index:0;
}
kernel float test4(float4 vol<>,float4 index<>){
  float4 zero4 = 0;  float4 isovalue=.39;  float4 tmp = (vol>isovalue)?index:zero4;  return dot(tmp,1);}
/* This kernel is for a synthetic dataset consisting of one sphere centered at
 * offset and radius equal to sqrt(density). 
 * Not used for normal datasets.
 */
kernel float synthEval(float3 loc<>) {
  float  power;
  const float3 offset=1;
  float3 center =loc-offset;
  power = dot(center,center);

  //uncomment following to enable 8 spheres. Too many for nCidia or ATI
  /* 
  {
  const float length=20;
  center.x +=length;
  power += dot(center,center);
  center.y+=length;
  power += dot(center,center);
  center.x-= length;
  power +=  dot(center,center);
  center.z+= length;
  power += dot(center,center);
  
  center.y-=length;
  power += dot(center,center);
  
  center.x+=length;                  
  power += dot(center,center);
  center.y+=length;
  power += dot(center,center);
  }
  */
  {

     const float  density =.5*.5;
    //printf (power,loc.z,density,power-density);
     return 1;    return density-power;
  }
}

/** This kernel is for the synthetic sphere dataset and evaluates
 *  The set of spheres for each of the neighbors and tests them > 0
 *  for each neighbor.  The final values are added together to produce a lookup
 *  index */
kernel float synthEvaluateNeighbors (float2 center<>,
                                float2 opposing<>,
                                float2 slice) {

   float a=test(synthEval(float3(center.x,center.y,slice.x)),1.0f) +
      test(synthEval(float3(center.x,opposing.y,slice.x)),2.0f) +
      test(synthEval(float3(opposing.x,opposing.y,slice.x)),4.0f) +
      test(synthEval(float3(opposing.x,center.y,slice.x)),8.0f) +
      test(synthEval(float3(center.x,center.y,slice.y)),16.0f) +
      test(synthEval(float3(center.x,opposing.y,slice.y)),32.0f) +
      test(synthEval(float3(opposing.x,opposing.y,slice.y)),64.0f) +
      test(synthEval(float3(opposing.x,center.y,slice.y)),128.0f);
   return a>0.5f&&a<(2.0f+4.0f+8.0f+16.0f+32.0f+64.0f+128.0f+0.5f)?a:0;
    
}
/** This kernel is for the synthetic sphere dataset and evaluates
 *  the neighbor values, and gets the lookup index for the triangle dataset
 *  Only pushes a result if the index is not 0 (empty case)
 **/
kernel void processSyntheticSlice(vout[1] float4 vertex<>,
                                iter float2 center<>,
                                iter float2 opposing<>,
                                float2 slice/*first value is cur then next*/) {
  float pattern;
  if((pattern=synthEvaluateNeighbors(center,opposing,slice))) {
    vertex=float4(center.x,center.y,slice.x,pattern);
    push(vertex);
  }
}
/** This kernel is for the synthetic sphere dataset and evaluates
 *  the neighbor values, and gets the lookup index for the triangle dataset
 *  It pushes a negative index in the event that all or none of the neighbors
 *  are dense enough */
kernel void processSyntheticSliceNoCompact(out float4 vertex<>,
                                           iter float2 center<>,
                                           iter float2 opposing<>,
                                           float2 slice
                                           /*first value is cur then next*/) {
  float pattern;
  if((pattern=synthEvaluateNeighbors(center,opposing,slice))) {
    vertex=float4(center.x,center.y,slice.x,pattern);
  }else {
    vertex=float4(-1.0,-1.0f,-1.0f,-1.0f);
  }
}

/** This kernel is for the experimental dataset and evaluates
 *  the neighbor values, and gets the lookup index for the triangle dataset
 *  Only pushes a result if the index is not 0 or 255 (empty cases)
 **/
kernel void processSlice (float curgather[][],
                          float nextslice[][],
                          vout [1]float4 vertex<>,
                          iter float2 center<>,
                          iter float2 up<>,
                          iter float2 forward<>,
                          iter float2 upforward<>,
                          float2 slice) {
  float4 o248={1.0f,2.0f,4.0f,8.0f};  float4 t456={16.0f,32.0f,64.0f,128.0f};  float4 cur={curgather[center],curgather[up],curgather[upforward],curgather[forward]};  float4 next={nextslice[center],nextslice[up],nextslice[upforward],nextslice[forward]};  float a=    test4(cur,o248)+    test4(next,t456);  if (a>0.5f&&a<254.5f) {
    vertex=float4(center.x,center.y,slice.x,a);
    push(vertex);
  }
}

/** This kernel is for the synthetic sphere dataset and evaluates
 *  the neighbor values, and gets the lookup index for the triangle dataset
 *  It pushes a negative index in the event that all or none of the neighbors
 *  are dense enough */
kernel void processSliceNoCompact (float curgather[][],
                                   float nextslice[][],
                                   out float4 vertex<>,
                                   iter float2 center<>,
                                   iter float2 up<>,
                                   iter float2 forward<>,
                                   iter float2 upforward<>,
                                   float2 slice) {
  float a=
    test(curgather[center],1.0f)+
    test(curgather[up],2.0f)+
    test(curgather[upforward],4.0f)+
    test(curgather[forward],8.0f)+
    test(nextslice[center],16.0f)+
    test(nextslice[up],32.0f)+
    test(nextslice[upforward],64.0f)+
    test(nextslice[forward],128.0);
  if (a>0.5f&&a<(2.0f+4.0f+8.0f+16.0f+32.0f+64.0f+128.0f+0.5f)) {
    vertex=float4(center.x,center.y,slice.x,a);
  }else {
    vertex=float4(-1,-1,-1,-1);
  }
  
}
                           
/** This kernel outputs exactly 5 triangles for each input
 *  lookup value. It assumes the sentinel is immutable with respect to 
 *  addition (i.e. inf behaves this way)
 *  Given that up to five triangles are produced for each volumetric datapoint
 *  exactly five triangles are outputted reguardless.
 *  The vertex is determined based on the index mod 3... the output triangles
 *  are stretched to 3x the input so that each of the 3 requisite vertices
 *  are produced per output.
 */
kernel void processTrianglesNoCompact(out float3 trianglesA<>, 
                                      out float3 trianglesB<>, 
                                      out float3 trianglesC<>,
                                      out float3 trianglesD<>, 
                                      out float3 trianglesE<>, 
                                      float4 vertices1<>,
                                      float3 volumeTriangles[][]) {
  float4 whichVolumeTriangle={round(fmod((indexof trianglesA).x,3)),vertices1.w,0,0};
  float3 vertices=vertices1.xyz;
  if (!(whichVolumeTriangle.y<256&&whichVolumeTriangle.y>=0))

    whichVolumeTriangle.y=0;

  if (whichVolumeTriangle.x+.5>3) whichVolumeTriangle.x=0;
  trianglesA=vertices.xyz+volumeTriangles[whichVolumeTriangle];
  whichVolumeTriangle.x+=3;
  trianglesB=vertices.xyz+volumeTriangles[whichVolumeTriangle];
  whichVolumeTriangle.x+=3;
  trianglesC=vertices.xyz+volumeTriangles[whichVolumeTriangle];
  whichVolumeTriangle.x+=3;  
  trianglesD=vertices.xyz+volumeTriangles[whichVolumeTriangle];  
  whichVolumeTriangle.x+=3;  
  trianglesE=vertices.xyz+volumeTriangles[whichVolumeTriangle];  
}
kernel float4 interp (float4 a, float4 b) {  return lerp (0,1,1-(.39-a)/(b-a));  }kernel void processTrianglesNoCompactOneOut(out float3 trianglesA<>, 
                                            float4 verticesinf<>,
                                            float3 volumeTriangles[][],                                            float curgather[][],
                                            float nextgather[][]) {
  float isovalue=.39;  float2 threefive={3.0f,5.0f};  float2 onehalf2=.5;  float2 zero2=0;  float4 four256=256;  float4 vertices1=(verticesinf<four256&&verticesinf>=zero2.xxxx)    ? verticesinf    : zero2.xxxx;  float2 whichVolumeTriangle={0,vertices1.w};
  float3 vertices=vertices1.xyz;  float2 mod35=round(fmod((indexof trianglesA).xy,threefive));  mod35 = (mod35+onehalf2>threefive)?zero2:mod35;  whichVolumeTriangle.x=mod35.x+mod35.y*3;   {    float3 configinf = volumeTriangles[whichVolumeTriangle].xyz;    float3 config = configinf<four256.xxx?configinf:zero2.xxx;    float low,high;    float3 ishalf,tmp;    ishalf=(float3)config==onehalf2.x;    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+config;  }   }/*kernel void processTrianglesNoCompactOneOut(out float3 trianglesA<>, 
                                      float4 vertices1<>,
                                      float3 volumeTriangles[][]) {
  float4 whichVolumeTriangle={round(fmod((indexof trianglesA).x,15)),vertices1.w,0,0};
  float3 vertices=vertices1.xyz;
  if (!(whichVolumeTriangle.y<256&&whichVolumeTriangle.y>=0))

    whichVolumeTriangle.y=0;

  if (whichVolumeTriangle.x+.5>15) whichVolumeTriangle.x=0;
  trianglesA=vertices.xyz+volumeTriangles[whichVolumeTriangle];
  }
*/
/** This kernel outputs exactly 5 triangles for each input
 *  lookup value. It assumes the sentinel is not between -.75 and .75
 *  Given that up to five triangles are produced for each volumetric datapoint
 *  The output stream is stretched to 4x the input stream size, and either 0 or
 *  3 vertices are produced for the given volumeTriangle lookup.
 */

kernel void processTriangles(vout[1] float4 triangles<>, 
                             float4 vertices<>,
                             float3 volumeTriangles[][],
                             iter float2 streamsize<>) {
 float4 whichVolumeTriangle={fmod(streamsize.y,5.0f)*3.0f,vertices.w,0,0}; float3 firstTrianglePos; if (whichVolumeTriangle.x+.5>15.0f) whichVolumeTriangle.x=3.0f; if (!(whichVolumeTriangle.y<256&&whichVolumeTriangle.y>=0))   whichVolumeTriangle.y=0; firstTrianglePos=volumeTriangles[whichVolumeTriangle]; if (abs(firstTrianglePos.x-.5)<.75) {   triangles.xy=(indexof vertices).xy;   triangles.zw = whichVolumeTriangle.xy;   push(triangles); }  }/**
 * Since every one of the outputted volumeTriangle lookup indices has at least 
 * one triangle, the first triangle is a guaranteed hit and need not be 
 * conditionally produced. 
 * Hence the triangle is looked up, and produced. The respective vertex is
 * computed depending on the fmod with 3
 */
kernel void processFirstTriangles(out float3 triangles<>, 
                                  float4 vertices<>,
                                  float3 volumeTriangles[][]) {

    float4 whichVolumeTriangle={round(fmod((indexof triangles).x,3.0f)),vertices.w,0,0};
   if (whichVolumeTriangle.x+.5>3.0f) whichVolumeTriangle.x=0.0f;
   if (!(whichVolumeTriangle.y<256&&whichVolumeTriangle.y>=0))
      whichVolumeTriangle.y=0;
   triangles=vertices.xyz;
     //   if (whichVolumeTriangle.y<256&&whichVolumeTriangle.y>=0)
   triangles+=volumeTriangles[whichVolumeTriangle];
}

typedef float3 Triangle[5][3];
/**
 * The following function generates the triangle lookup table from the raw
 * edge list data stored in volume_division.h
 * First it fills everything with the sentinel.
 * Then it goes through up to 15 items, filling the triangle table until a 
 * -1 in the edge list is encountered at which point it stops adding to the tex
 */
char volumeTriangles(Triangle tri[256]) {
  unsigned int i,j,k,m;

   for (i=0;i<256;++i) {
      for (m=0;m<15;++m) {
        // fill with sentinel
         tri[i][(m/3)%5][m%3]=float3(1.0f/(float)floor(.5),
                                     1.0f/(float)floor(.5),
                                     1.0f/(float)floor(.5));
      }
      j=0;
      for (j=0;;j+=3) {
         if (m_triTable[i][j]==-1){// our edge list is -1, stop!
           m_triNum[i]=(float)(j/3);//set the count of triangles to j
           break; // it's too dangerous we have to slow down first!
         }
         for (k=0;k<3;++k) {
           // single out the point that will be set on this pass
            float3 * p=&tri[i][j/3][k];
            p->x=m_triTable[i][j+k];// for debugging only, overwritten
            p->y=m_triTable[i][j+k];// for debugging only
            p->z=m_triTable[i][j+k];// for debugging only
            switch ((int)m_triTable[i][j+k]) {
              // set the appropriate coordinates in a 1x1x1 cube
              // given the lookup value assuming the data is exactly
              // in the middle--i.e. no adaptive
            case 0:
               p->x=p->z=0;p->y=0.5f;
               break;
            case 1:
               p->x=0.5f;p->z=0;p->y=1.0f;
               break;
            case 2:
               p->x=1.0f;p->z=0;p->y=0.5f;
               break;
            case 3:
               p->x=0.5f;p->z=0;p->y=0;
               break;
            case 4:
               p->x=0;p->z=1.0f;p->y=0.5f;
               break;
            case 5:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -