Text archives Help
- From: hansong@sci.utah.edu
- To: manta@sci.utah.edu
- Subject: [MANTA] r1093 - in trunk: Model/Groups Model/Materials scenes
- Date: Fri, 2 Jun 2006 20:04:09 -0600 (MDT)
Author: hansong
Date: Fri Jun 2 20:04:06 2006
New Revision: 1093
Added:
trunk/Model/Materials/CopyColorMaterial.cc
trunk/Model/Materials/CopyColorMaterial.h
Modified:
trunk/Model/Groups/VolumeGrid.h
trunk/Model/Materials/CMakeLists.txt
trunk/scenes/volume.cc
Log:
(1) make volume rendering (VolumeGrid.h) work with top of the
trunk again. (adding back CopyColorMaterial in the process)
Note: volume rendering functionality is restored using
the legacy interface to RayPacket, so performance isn't
optimal
(2) Added an in-memory load() interface to VolumeGrid, so that
other applications can hook into Manta. A VTK-based app
will probably be the first to use the interface
(3) the volume scene (scenes/volume.cc) is updated to have a
default dyanically created volume. This exercises the
in-memory load interface. A example command to run volume
rendering is
bin/dm_demo -np 32 -scene lib/libscene_volume.so'(-tf test.tf)'
-camera 'pinhole(-eye 300 300 300 -lookat 64 64 64 -up 0 1 0)
The default scene is used (since no "-file vol_desc_file" argument
is given. The ad-hoc transfer function file, "test.tf", is a text
file with # of entries in the first line and subsequent lines of
the format
Value R G B A
For example:
2048
0 1.0 0.0 0.0 0.2
128 1.0 1.0 0.0 0.2
256 1.0 0.0 0.5 0.01
512 0.0 0.0 1.0 0.01
1023 0.0 1.0 1.0 0.01
2047 0.0 1.0 1.0 .01
can be used with the default volume.
(4) To invoke the volume renderer with a raw volume, first write a
volume description file that mimics the following (brain.dsc)
dimensions: 181 217 180
components: 1
component size: 1
voxel scale: 1 1 1
datafile: brainweb165a10f17.raw
z block size: 64 // not used in Manta
z levels: 5 // not used in Manta
Then, invoke Manta like
bin/dm_demo -np 32 -scene lib/libscene_volume.so'(-np 32 -file
brain.dsc -tf test8.tf)' -camera 'pinhole(-eye 100 500 100 -lookat 100 100
100 -up 1 0 0)'
(5) To use volume rendering, you must set SCENE_VOLUME to ON in ccmake.
SCENE_FOX should also be on to use example command lines above.
Modified: trunk/Model/Groups/VolumeGrid.h
==============================================================================
--- trunk/Model/Groups/VolumeGrid.h (original)
+++ trunk/Model/Groups/VolumeGrid.h Fri Jun 2 20:04:06 2006
@@ -2,6 +2,7 @@
#define __SPATIAL_H__
#include <Model/Groups/Group.h>
+#include <Model/Primitives/PrimitiveCommon.h>
#include <Core/Geometry/Vector.h>
#include <Core/Geometry/BBox.h>
#include <Model/Intersections/AxisAlignedBox.h>
@@ -21,6 +22,10 @@
#define GAMMA_TABLE_SIZE 512
namespace Manta {
+#define Vec3f VectorT<float,3>
+#define Point3f PointT<float,3>
+#define Vec4f VectorT<float,4>
+
struct AABox3f {
Vec3f min, max;
@@ -468,13 +473,18 @@
}
};
+ typedef void (*DATAREADCALLBACK)(void *ptr, size_t itemSize, size_t
nItems,
+ void* cbData);
+
template <class VoxelType>
class VolumeGrid : public __Grid<
MultiResVolumeCube<VoxelType> > {
//VoxelType _minVal, _maxVal;
Vec3f _voxelScale;
VolumeRenderingParams *_vrp;
- *_ccm;
+ CopyColorMaterial *_ccm;
+
public:
+
VolumeGrid() : __Grid< MultiResVolumeCube<VoxelType>
>
() {
_ccm = new CopyColorMaterial;
}
@@ -503,6 +513,10 @@
}
int load(const char *dscfn, int cubeSize, bool
compressed,
int discarded_levels);
+ int load(int xn, int yn, int zn, int compSize,
+ float scalex, float scaley, float
scalez,
+ int cubeSize,
+ DATAREADCALLBACK readCB, void
*readCBData);
void intersect(const RenderContext& context,
RayPacket& rays) const {
@@ -510,39 +524,42 @@
// As a side effect this also computes the
sign mask for the box intersection.
rays.normalizeDirections();
rays.computeInverseDirections();
+ rays.computeSigns();
- for(int i=0;i<rays.getSize();i++) {
+ //for(int i=0;i<rays.getSize();i++) {
+ for(int i=rays.begin();i<rays.end();i++) {
- RayPacket::Element& e = rays.get(i);
+ const Ray &e = rays.getRay(i);
Real minDist, maxDist;
// Intersect the ray with the
bounding box for the group.
if
(Intersection::intersectAaBox(_bound,
minDist,
maxDist,
- e.ray,
- e.signMask,
-
e.inverseDirection )) {
+
rays.getRay(i),
+
rays.getSigns(i),
+
rays.getInverseDirection(i) )) {
// Determine the actual
minimum distance.
- minDist = SCIRun::Max(
minDist, (Real)T_EPSILON );
- maxDist = SCIRun::Min(
maxDist, e.hitInfo.minT() );
+ minDist = SCIRun::Max(
minDist, T_EPSILON );
+ maxDist = SCIRun::Min(
maxDist, rays.getMinT(i) );
// March the ray through the
volume
Vec4f accumCO;
- traverseGrid(&e.ray,
(float)minDist, (float)maxDist,
+ traverseGrid(&rays.getRay(i),
+
(float)minDist, (float)maxDist,
accumCO,
_vrp->maxOpacity, _vrp->tf,
_vrp->stepScale, _vrp->attenFactor);
// Send the color output to
Manta
- unsigned char r, g, b, a;
- r = (unsigned
char)(accumCO[0] * 255);
- g = (unsigned
char)(accumCO[1] * 255);
- b = (unsigned
char)(accumCO[2] * 255);
- a = (unsigned
char)(accumCO[3] * 255);
- if (e.hitInfo.hit(T_EPSILON,
_ccm, (Primitive*)1, 0 )) {
- //
e.hitInfo.scratchpad<unsigned int>() =
- //
(a<<24)+(r<<16)+(g<<8)+b;
+ unsigned int r, g, b, a;
+ r = (unsigned int)(accumCO[0]
* 255);
+ g = (unsigned int)(accumCO[1]
* 255);
+ b = (unsigned int)(accumCO[2]
* 255);
+ a = (unsigned int)(accumCO[3]
* 255);
+ if (rays.hit(i, T_EPSILON,
_ccm, (Primitive*)1, 0 )) {
+
rays.scratchpad<unsigned int>(i) =
+
(a<<24)+(r<<16)+(g<<8)+b;
}
}
}
@@ -1159,6 +1176,119 @@
return 1;
}
+
+template <class VoxelType>
+int VolumeGrid<VoxelType>::load(int xn, int yn, int zn,
+ int compSize, float scalex, float scaley, float scalez,
+ int cubeSize, DATAREADCALLBACK readCB,
+ void *readCBData)
+{
+ long long i, j, k;
+ VolumeDescription vd;
+ int x, y, z;
+ int ncomp;
+ int comp_size;
+ char data_file_name[512];
+ int z_chunk_size;
+ int z_levels;
+ void *data;
+
+ vd.x = xn;
+ vd.y = yn;
+ vd.z = zn;
+ vd.ncomp = 1;
+ vd.comp_size = compSize;
+ vd.scalex = scalex;
+ vd.scaley = scaley;
+ vd.scalez = scalez;
+
+ int alignment = 16384;
+ int fileBlockSize = 4*1024;
+ long long nvoxels = (long long)vd.x*vd.y*cubeSize;
+ size_t maxread = 512 * 1024;
+ VoxelType * vol = new VoxelType [nvoxels+alignment];
+ VoxelType *origVol = vol;
+ vol = (VoxelType*)(((long long)vol + alignment)/alignment*alignment);
+
+ unsigned char * readBuf = new unsigned char [maxread + alignment];
+ unsigned char *origReadBuf = readBuf;
+ readBuf = (unsigned char*)(((long long)readBuf +
alignment)/alignment*alignment);
+
+ fprintf(stderr, "vol buf: %p read buf: %p\n", vol, readBuf);
+#pragma omp parallel for private(i)
+ for (i=0; i<nvoxels; i+=4096)
+ vol[i]=0;
+
+ VolumeGrid<VoxelType> *vg = this;
+
+ vg->initByBoundAndCellSize(Vec3f(0, 0, 0),
+ Vec3f(vd.x, vd.y, vd.z), cubeSize,
+ Vec3f(vd.scalex,vd.scaley,vd.scalez));
+
+ int loadCubeSize = cubeSize;
+
+ // Now, init each cell
+ long numCells = vg->getNumCells();
+ int subd[3];
+ vg->getNumSubdiv(subd);
+ int cellIdx;
+ MultiResVolumeCube<VoxelType> * cell;
+ AABox3f __bound[512];
+ AABox3f *bound;
+ VolumeCube<VoxelType> * cube;
+ int xx0, yy0, zz0;
+ long long xx, yy, zz;
+ int w, h, d;
+ double fxx, fyy, fzz;
+ double fw, fh, fd;
+ int retx, rety, retz;
+ int nsubd = subd[0]*subd[1]*subd[2];
+ VoxelType *buf;
+ bool fullCube;
+ int cellZ;
+ int nCellsInCubeSlice = subd[0]*subd[1];
+ long long totalNumRemainingVoxels = (long long)vd.x*vd.y*vd.z;
+ for (cellZ=0; cellZ<subd[2]; cellZ++) {
+ readCB(vol, sizeof(VoxelType), nvoxels, readCBData);
+ fprintf(stderr, "%d ", cellZ);
+
+#pragma omp parallel for
private(i,j,k,x,y,z,cellIdx,cell,bound,cube,xx0,yy0,zz0,xx,yy,zz,w,h,d,fxx,fyy,fzz,fw,fh,fd,retx,rety,retz,buf,fullCube)
schedule(static,2)
+ for (cellIdx=0; cellIdx<nCellsInCubeSlice; cellIdx++) {
+ x = cellIdx % subd[0];
+ y = (cellIdx / subd[0]) % subd[1];
+ z = cellZ; //cellIdx / (subd[0]*subd[1]);
+
+ cell = vg->getCellAlloc(x, y, z);
+#ifdef _OPENMP
+ bound = &__bound[omp_get_thread_num()];
+#else
+ bound = &__bound[0];
+#endif
+ vg->getCellBound(bound, x, y, z);
+ cell->init(cubeSize, 4, *bound);
+ cube = new VolumeCube<VoxelType>(loadCubeSize);
+ cube->clear();
+ cell->setLevel(0, cube);
+
+ // fill the cube
+ xx0=x*cubeSize, yy0=y*cubeSize, zz0=0; //=z*cubeSize;
+ w = h = d = cubeSize;
+ if (xx0+w > vd.x) w = vd.x-xx0;
+ if (yy0+h > vd.y) h = vd.y-yy0;
+ if (zz0+cubeSize*z+d > vd.z) d = vd.z-z*cubeSize-zz0;
+ for (zz=zz0; zz<zz0+d; zz++)
+ for (yy=yy0; yy<yy0+h; yy++)
+ for (xx=xx0; xx<xx0+w; xx++) {
+ cube->set(xx-xx0, yy-yy0,
zz-zz0,
+
vol[xx+yy*vd.x+zz*vd.x*vd.y]);
+ }
+ }
+ }
+
+ delete [] origVol;
+
+ return 1;
+}
} // namespace
#endif
Modified: trunk/Model/Materials/CMakeLists.txt
==============================================================================
--- trunk/Model/Materials/CMakeLists.txt (original)
+++ trunk/Model/Materials/CMakeLists.txt Fri Jun 2 20:04:06 2006
@@ -22,6 +22,8 @@
Materials/Phong.cc
Materials/Transparent.cc
Materials/Transparent.h
+ Materials/CopyColorMaterial.cc
+ Materials/CopyColorMaterial.h
)
IF(BUILD_DYNPLT)
Added: trunk/Model/Materials/CopyColorMaterial.cc
==============================================================================
--- (empty file)
+++ trunk/Model/Materials/CopyColorMaterial.cc Fri Jun 2 20:04:06 2006
@@ -0,0 +1,40 @@
+
+#include <Model/Materials/CopyColorMaterial.h>
+#include <Interface/Light.h>
+#include <Interface/LightSet.h>
+#include <Interface/Primitive.h>
+#include <Interface/RayPacket.h>
+#include <Interface/AmbientLight.h>
+#include <Interface/Context.h>
+#include <Interface/ShadowAlgorithm.h>
+#include <Model/Textures/Constant.h>
+#include <Interface/Scene.h>
+
+#include <Model/Groups/KDTree.h>
+
+using namespace Manta;
+
+void KDTreeCopyColorMaterial::shade(const RenderContext& /*context*/,
+ RayPacket& rays) const {
+
+}
+
+void CopyColorMaterial::shade(const RenderContext& /*context*/,
+ RayPacket& rays) const {
+
+ for (int i=rays.begin();i<rays.end();i++) {
+ unsigned int payload = rays.scratchpad<unsigned int>(i);
+ // unsigned char *c = (unsigned char *)&payload;
+
+ Color result( RGB(
+ ((payload & 0x00ff0000)>>16)*0.0039f,
+ ((payload & 0x0000ff00)>>8)*0.0039f,
+ ((payload & 0x000000ff))*0.0039f));
+
+ rays.setColor( i, result );
+ }
+}
+
+
+
+
Added: trunk/Model/Materials/CopyColorMaterial.h
==============================================================================
--- (empty file)
+++ trunk/Model/Materials/CopyColorMaterial.h Fri Jun 2 20:04:06 2006
@@ -0,0 +1,29 @@
+
+#ifndef Manta_Model_CopyColor_h
+#define Manta_Model_CopyColor_h
+
+#include <Interface/Material.h>
+#include <Interface/Context.h>
+#include <Interface/RayPacket.h>
+namespace Manta{
+
+ // This material is used with the KDTree's to copy a color out of the
+ // hit record which was computed during intersection.
+ class KDTreeCopyColorMaterial : public Material {
+ public:
+ KDTreeCopyColorMaterial() { }
+ virtual ~KDTreeCopyColorMaterial() { }
+ virtual void preprocess(const PreprocessContext&) { }
+ virtual void shade(const RenderContext& context, RayPacket& rays) const;
+ };
+
+ class CopyColorMaterial : public Material {
+ public:
+ CopyColorMaterial() { }
+ virtual ~CopyColorMaterial() { }
+ virtual void preprocess(const PreprocessContext&) { }
+ virtual void shade(const RenderContext& context, RayPacket& rays) const;
+ };
+}
+
+#endif
Modified: trunk/scenes/volume.cc
==============================================================================
--- trunk/scenes/volume.cc (original)
+++ trunk/scenes/volume.cc Fri Jun 2 20:04:06 2006
@@ -20,7 +20,6 @@
#include <Model/Lights/HeadLight.h>
#include <Model/Materials/Lambertian.h>
#include <Model/Materials/MetalMaterial.h>
-#include <Model/Materials/NormalMaterial.h>
#include <Model/Primitives/Parallelogram.h>
#include <Model/Primitives/Sphere.h>
#include <Model/Textures/CheckerTexture.h>
@@ -39,6 +38,27 @@
enum CuttingPlaneType { CUTTING_NONE, CUTTING_DEFAULT, CUTTING_SPECIFIED };
+#define TEST_VOL_SIZE 128
+short *g_testVol;
+short *g_testVolCurPtr;
+
+void InitTestVolume()
+{
+ int i, j, k;
+ g_testVol =
(short*)malloc(sizeof(short)*TEST_VOL_SIZE*TEST_VOL_SIZE*TEST_VOL_SIZE);
+ g_testVolCurPtr = g_testVol;
+ for (i=0; i<TEST_VOL_SIZE; i++)
+ for (j=0; j<TEST_VOL_SIZE; j++)
+ for (k=0; k<TEST_VOL_SIZE; k++)
+ g_testVol[i*TEST_VOL_SIZE*TEST_VOL_SIZE+j*TEST_VOL_SIZE+k] =
(i+j+k)*2;
+}
+
+void ReadCB(void *ptr, size_t itemSize, size_t nItems, void* cbData)
+{
+ memcpy(ptr, g_testVolCurPtr, itemSize*nItems);
+ g_testVolCurPtr += nItems;
+}
+
///////////////////////////////////////////////////////////////////////////
extern "C"
Scene* make_scene(const ReadContext& context, const vector<string>& args) {
@@ -98,28 +118,40 @@
VolumeRenderingParams *vrp = new VolumeRenderingParams(tf);
VolumeDescription vd;
- vd.load(file_name.c_str());
-if (vd.comp_size == 1) {
+ if (file_name.size() && vd.load(file_name.c_str())) {
+ if (vd.comp_size == 1) {
- VolumeGrid<unsigned char> *vg = new VolumeGrid<unsigned char>;
- vg->load(file_name.c_str(), 128, false, 0);
- group->add(vg);
+ VolumeGrid<unsigned char> *vg = new
VolumeGrid<unsigned char>;
+ vg->load(file_name.c_str(), 128, false, 0);
+ group->add(vg);
- vg->setVolumeRenderingParams(vrp);
+ vg->setVolumeRenderingParams(vrp);
- bounds = vg->getBound();
-} else {
- TransferFunction *tf = new TransferFunction();
- tf->load( tf_name.c_str() );
+ bounds = vg->getBound();
+ } else {
+ TransferFunction *tf = new TransferFunction();
+ tf->load( tf_name.c_str() );
- VolumeGrid<short> *vg = new VolumeGrid<short>;
- vg->load(file_name.c_str(), 128, false, 0);
- group->add(vg);
+ VolumeGrid<short> *vg = new VolumeGrid<short>;
+ vg->load(file_name.c_str(), 128, false, 0);
+ group->add(vg);
- vg->setVolumeRenderingParams(vrp);
+ vg->setVolumeRenderingParams(vrp);
- bounds = vg->getBound();
-}
+ bounds = vg->getBound();
+ }
+ } else {
+ InitTestVolume();
+
+ VolumeGrid<short> *vg = new VolumeGrid<short>;
+ vg->load(TEST_VOL_SIZE, TEST_VOL_SIZE, TEST_VOL_SIZE,
+ sizeof(short), 1, 1, 1,
+ 64, ReadCB, NULL);
+ vg->setVolumeRenderingParams(vrp);
+
+ group->add(vg);
+ bounds = vg->getBound();
+ }
LightSet *lights = new LightSet();
- [MANTA] r1093 - in trunk: Model/Groups Model/Materials scenes, hansong, 06/02/2006
Archive powered by MHonArc 2.6.16.