44 #ifndef OPENVDB_TOOLS_RAYTRACER_HAS_BEEN_INCLUDED
45 #define OPENVDB_TOOLS_RAYTRACER_HAS_BEEN_INCLUDED
47 #include <openvdb/Types.h>
48 #include <openvdb/math/BBox.h>
49 #include <openvdb/math/Ray.h>
50 #include <openvdb/math/Math.h>
51 #include <openvdb/tools/RayIntersector.h>
52 #include <boost/scoped_ptr.hpp>
55 #ifdef OPENVDB_TOOLS_RAYTRACER_USE_EXR
56 #include <OpenEXR/ImfPixelType.h>
57 #include <OpenEXR/ImfChannelList.h>
58 #include <OpenEXR/ImfOutputFile.h>
59 #include <OpenEXR/ImfHeader.h>
60 #include <OpenEXR/ImfFrameBuffer.h>
73 template<
typename Gr
idT>
77 size_t pixelSamples = 1,
78 unsigned int seed = 0,
79 bool threaded =
true);
82 template<
typename Gr
idT,
typename IntersectorT>
87 size_t pixelSamples = 1,
88 unsigned int seed = 0,
89 bool threaded =
true);
96 template<
typename Gr
idT,
typename IntersectorT = tools::LevelSetRayIntersector<Gr
idT> >
102 typedef typename IntersectorT::RayType
RayType;
108 size_t pixelSamples = 1,
109 unsigned int seed = 0);
116 size_t pixelSamples = 1,
117 unsigned int seed = 0);
126 void setGrid(
const GridT& grid);
130 void setIntersector(
const IntersectorT& inter);
148 void setPixelSamples(
size_t pixelSamples,
unsigned int seed = 0);
151 void render(
bool threaded =
true);
156 void operator()(
const tbb::blocked_range<size_t>& range)
const;
159 const bool mIsMaster;
162 boost::scoped_ptr<const BaseShader> mShader;
181 RGBA() : r(0), g(0), b(0), a(1) {}
182 explicit RGBA(
ValueT intensity) : r(intensity), g(intensity), b(intensity), a(1) {}
192 const float s = rhs.
a*(1.0f-a);
203 Film(
size_t width,
size_t height)
204 : mWidth(width), mHeight(height), mSize(width*height), mPixels(new
RGBA[mSize])
208 : mWidth(width), mHeight(height), mSize(width*height), mPixels(new
RGBA[mSize])
218 return mPixels[w + h*mWidth];
225 return mPixels[w + h*mWidth];
228 void fill(
const RGBA& rgb=
RGBA(0)) {
for (
size_t i=0; i<mSize; ++i) mPixels[i] = rgb; }
232 for (
size_t j = 0; j < mHeight; ++j) {
233 for (
size_t i = 0; i < mWidth; ++i, ++p) {
234 *p = ((i & size) ^ (j & size)) ? c1 : c2;
241 std::string name(fileName +
".ppm");
242 unsigned char* tmp =
new unsigned char[3*mSize], *q = tmp;
246 *q++ =
static_cast<unsigned char>(255.0f*(*p ).r);
247 *q++ =
static_cast<unsigned char>(255.0f*(*p ).g);
248 *q++ =
static_cast<unsigned char>(255.0f*(*p++).b);
251 std::ofstream os(name.c_str(), std::ios_base::binary);
253 std::cerr <<
"Error opening PPM file \"" << name <<
"\"" << std::endl;
257 os <<
"P6\n" << mWidth <<
" " << mHeight <<
"\n255\n";
258 os.write((
const char *)&(*tmp), 3*mSize*
sizeof(
unsigned char));
262 #ifdef OPENVDB_TOOLS_RAYTRACER_USE_EXR
263 void saveEXR(
const std::string& fileName,
size_t compression = 2,
size_t threads = 8)
265 std::string name(fileName +
".exr");
267 if (threads>0) Imf::setGlobalThreadCount(threads);
268 Imf::Header header(mWidth, mHeight);
269 if (compression==0) header.compression() = Imf::NO_COMPRESSION;
270 if (compression==1) header.compression() = Imf::RLE_COMPRESSION;
271 if (compression>=2) header.compression() = Imf::ZIP_COMPRESSION;
272 header.channels().insert(
"R", Imf::Channel(Imf::FLOAT));
273 header.channels().insert(
"G", Imf::Channel(Imf::FLOAT));
274 header.channels().insert(
"B", Imf::Channel(Imf::FLOAT));
275 header.channels().insert(
"A", Imf::Channel(Imf::FLOAT));
277 Imf::FrameBuffer framebuffer;
278 framebuffer.insert(
"R", Imf::Slice( Imf::FLOAT, (
char *) &(mPixels[0].r),
279 sizeof (RGBA),
sizeof (RGBA) * mWidth));
280 framebuffer.insert(
"G", Imf::Slice( Imf::FLOAT, (
char *) &(mPixels[0].g),
281 sizeof (RGBA),
sizeof (RGBA) * mWidth));
282 framebuffer.insert(
"B", Imf::Slice( Imf::FLOAT, (
char *) &(mPixels[0].b),
283 sizeof (RGBA),
sizeof (RGBA) * mWidth));
284 framebuffer.insert(
"A", Imf::Slice( Imf::FLOAT, (
char *) &(mPixels[0].a),
285 sizeof (RGBA),
sizeof (RGBA) * mWidth));
287 Imf::OutputFile file(name.c_str(), header);
288 file.setFrameBuffer(framebuffer);
289 file.writePixels(mHeight);
293 size_t width()
const {
return mWidth; }
294 size_t height()
const {
return mHeight; }
299 size_t mWidth, mHeight, mSize;
311 double frameWidth,
double nearPlane,
double farPlane)
313 , mScaleWidth(frameWidth)
314 , mScaleHeight(frameWidth*film.height()/double(film.width()))
316 assert(nearPlane > 0 && farPlane > nearPlane);
317 mScreenToWorld.accumPostRotation(
math::X_AXIS, rotation[0] * M_PI / 180.0);
318 mScreenToWorld.accumPostRotation(
math::Y_AXIS, rotation[1] * M_PI / 180.0);
319 mScreenToWorld.accumPostRotation(
math::Z_AXIS, rotation[2] * M_PI / 180.0);
320 mScreenToWorld.accumPostTranslation(translation);
321 this->initRay(nearPlane, farPlane);
328 size_t width()
const {
return mFilm->width(); }
329 size_t height()
const {
return mFilm->height(); }
337 const Vec3R orig = mScreenToWorld.applyMap(
Vec3R(0.0));
338 const Vec3R dir = orig - xyz;
340 Mat4d xform = math::aim<Mat4d>(dir, up);
343 this->initRay(mRay.t0(), mRay.t1());
349 return Vec3R( (2 * i / mFilm->width() - 1) * mScaleWidth,
350 (1 - 2 * j / mFilm->height()) * mScaleHeight, z );
357 size_t i,
size_t j,
double iOffset = 0.5,
double jOffset = 0.5)
const = 0;
362 mRay.setTimes(t0, t1);
363 mRay.setEye(mScreenToWorld.applyMap(
Vec3R(0.0)));
364 mRay.setDir(mScreenToWorld.applyJacobian(
Vec3R(0.0, 0.0, -1.0)));
395 double focalLength = 50.0,
396 double aperture = 41.2136,
397 double nearPlane = 1e-3,
399 :
BaseCamera(film,
rotation, translation, 0.5*aperture/focalLength, nearPlane, farPlane)
409 size_t i,
size_t j,
double iOffset = 0.5,
double jOffset = 0.5)
const
412 Vec3R dir = BaseCamera::rasterToScreen(i + iOffset, j + jOffset, -1.0);
413 dir = BaseCamera::mScreenToWorld.applyJacobian(dir);
424 return 360.0 / M_PI * atan(aperture/(2.0*length));
430 return aperture/(2.0*(tan(fov * M_PI / 360.0)));
453 double frameWidth = 1.0,
454 double nearPlane = 1e-3,
462 size_t i,
size_t j,
double iOffset = 0.5,
double jOffset = 0.5)
const
465 Vec3R eye = BaseCamera::rasterToScreen(i + iOffset, j + jOffset, 0.0);
466 ray.
setEye(BaseCamera::mScreenToWorld.applyMap(eye));
491 return (*
this)(xyz, nml, ray.
dir());
522 return mRGBA*
Film::RGBA(normal[0]+1.0f, normal[1]+1.0f, normal[2]+1.0f);
537 : mMin(bbox.
min()), mInvDim(1.0/bbox.extents()), mRGBA(c) {}
541 const Vec3R rgb = (xyz - mMin)*mInvDim;
542 return mRGBA*
Film::RGBA(rgb[0], rgb[1], rgb[2]);
547 const Vec3R mMin, mInvDim;
582 template<
typename Gr
idT>
591 tracer(grid, shader, camera, pixelSamples, seed);
596 template<
typename Gr
idT,
typename IntersectorT>
598 const IntersectorT& inter,
613 template<
typename Gr
idT,
typename IntersectorT>
614 inline LevelSetRayTracer<GridT, IntersectorT>::
615 LevelSetRayTracer(
const GridT& grid,
623 mShader(shader.copy()),
629 template<
typename Gr
idT,
typename IntersectorT>
639 mShader(shader.copy()),
645 template<
typename Gr
idT,
typename IntersectorT>
650 mInter(other.mInter),
651 mShader(other.mShader->copy()),
652 mCamera(other.mCamera),
653 mSubPixels(other.mSubPixels)
657 template<
typename Gr
idT,
typename IntersectorT>
661 if (mIsMaster)
delete [] mRand;
664 template<
typename Gr
idT,
typename IntersectorT>
669 mInter = IntersectorT(grid);
672 template<
typename Gr
idT,
typename IntersectorT>
680 template<
typename Gr
idT,
typename IntersectorT>
685 mShader.reset(shader.
copy());
688 template<
typename Gr
idT,
typename IntersectorT>
696 template<
typename Gr
idT,
typename IntersectorT>
701 if (pixelSamples == 0) {
704 mSubPixels = pixelSamples - 1;
706 if (mSubPixels > 0) {
707 mRand =
new double[16];
709 for (
size_t i=0; i<16; ++i) mRand[i] = rand();
715 template<
typename Gr
idT,
typename IntersectorT>
719 tbb::blocked_range<size_t> range(0, mCamera->height());
720 threaded ? tbb::parallel_for(range, *
this) : (*this)(range);
723 template<
typename Gr
idT,
typename IntersectorT>
729 const float frac = 1.0f / (1.0f + mSubPixels);
730 for (
size_t j=range.begin(), n=0, je = range.end(); j<je; ++j) {
731 for (
size_t i=0, ie = mCamera->width(); i<ie; ++i) {
733 RayType ray = mCamera->getRay(i, j);
734 Film::RGBA c = mInter.intersectsWS(ray, xyz, nml) ? shader(xyz, nml, ray.dir()) : bg;
735 for (
size_t k=0; k<mSubPixels; ++k, n +=2 ) {
736 ray = mCamera->getRay(i, j, mRand[n & 15], mRand[(n+1) & 15]);
737 c += mInter.intersectsWS(ray, xyz, nml) ? shader(xyz, nml, ray.dir()) : bg;
748 #endif // OPENVDB_TOOLS_RAYTRACER_HAS_BEEN_INCLUDED
const Vec3T & dir() const
Definition: Ray.h:95
OPENVDB_API Hermite min(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
bool normalize(T eps=T(1.0e-7))
this = normalized this
Definition: Vec3.h:328
math::Vec3< Real > Vec3R
Definition: Types.h:74
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
Definition: Exceptions.h:88
void scaleTimes(RealT scale)
Definition: Ray.h:83
int32_t Abs(int32_t i)
Return the absolute value of the given quantity.
Definition: Math.h:253
MatType rotation(const Quat< typename MatType::value_type > &q, typename MatType::value_type eps=1.0e-8)
Definition: Mat.h:157
MatType scale(const Vec3< typename MatType::value_type > &scaling)
Definition: Mat.h:595
A general linear transform using homogeneous coordinates to perform rotation, scaling, shear and translation.
Definition: Maps.h:323
void setEye(const Vec3Type &eye)
Definition: Ray.h:69
#define OPENVDB_VERSION_NAME
Definition: version.h:45
Simple generator of random numbers over the range [0, 1)
Definition: Math.h:143
void postTranslate(const Vec3< T0 > &tr)
Right multiplies by the specified translation matrix, i.e. (*this) * Trans.
Definition: Mat4.h:728
void setDir(const Vec3Type &dir)
Definition: Ray.h:71
OPENVDB_API Hermite max(const Hermite &, const Hermite &)
min and max operations done directly on the compressed data.
Mat3< typename promote< T0, T1 >::type > operator*(const Mat3< T0 > &m0, const Mat3< T1 > &m1)
Matrix multiplication.
Definition: Mat3.h:608
Axis-aligned bounding box.
Definition: BBox.h:47
Vec3< typename promote< T, typename Coord::ValueType >::type > operator+(const Vec3< T > &v0, const Coord &v1)
Allow a Coord to be added to or subtracted from a Vec3.
Definition: Coord.h:382
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:67
T dot(const Vec3< T > &v) const
Dot product.
Definition: Vec3.h:199