Merge with upstream
commit
40cfc60ee7
|
@ -20,7 +20,7 @@ if sys.platform == 'win32':
|
||||||
# Set an application icon on Windows
|
# Set an application icon on Windows
|
||||||
resources += [ env.RES('data/windows/mitsuba_res.rc') ]
|
resources += [ env.RES('data/windows/mitsuba_res.rc') ]
|
||||||
# Convert the command line args from UTF-8 to UTF-16
|
# Convert the command line args from UTF-8 to UTF-16
|
||||||
winstubs += [os.path.abspath('data/windows/wmain_stub.cpp')]
|
winstubs += [ env.SharedObject('#data/windows/wmain_stub.cpp') ]
|
||||||
Export('winstubs')
|
Export('winstubs')
|
||||||
|
|
||||||
def build(scriptFile, exports = [], duplicate = 0):
|
def build(scriptFile, exports = [], duplicate = 0):
|
||||||
|
|
|
@ -285,7 +285,7 @@ if needsBuildDependencies:
|
||||||
print '\nThe dependency directory and your Mitsuba codebase have different version'
|
print '\nThe dependency directory and your Mitsuba codebase have different version'
|
||||||
print 'numbers! Your copy of Mitsuba has version %s, whereas the dependencies ' % MTS_VERSION
|
print 'numbers! Your copy of Mitsuba has version %s, whereas the dependencies ' % MTS_VERSION
|
||||||
print 'have version %s. Please bring them into sync, either by running\n' % depVersion
|
print 'have version %s. Please bring them into sync, either by running\n' % depVersion
|
||||||
print '$ hg update -r v%s\n' % depVersion
|
print '$ hg update -r v%s\n' % depVersion
|
||||||
print 'in the Mitsuba directory, or by running\n'
|
print 'in the Mitsuba directory, or by running\n'
|
||||||
print '$ cd dependencies'
|
print '$ cd dependencies'
|
||||||
print '$ hg pull'
|
print '$ hg pull'
|
||||||
|
@ -353,7 +353,7 @@ def configure_for_objective_cpp(env):
|
||||||
env.RemoveFlags(['-fstrict-aliasing', '-ftree-vectorize',
|
env.RemoveFlags(['-fstrict-aliasing', '-ftree-vectorize',
|
||||||
'-std=c\+\+0x'])
|
'-std=c\+\+0x'])
|
||||||
# Remove Intel compiler-specific optimization flags
|
# Remove Intel compiler-specific optimization flags
|
||||||
env.RemoveFlags(['-x.*', '-ax.*', '-ipo', '-no-prec-div',
|
env.RemoveFlags(['-x.*', '-ax.*', '-ipo', '-no-prec-div',
|
||||||
'-fp-model', 'fast=.*', '-wd.*', '-openmp'])
|
'-fp-model', 'fast=.*', '-wd.*', '-openmp'])
|
||||||
env['CCFLAGS'] += ['-fno-strict-aliasing']
|
env['CCFLAGS'] += ['-fno-strict-aliasing']
|
||||||
# Enforce GCC usage (Intel compiler doesn't handle Objective C/C++)
|
# Enforce GCC usage (Intel compiler doesn't handle Objective C/C++)
|
||||||
|
@ -374,7 +374,7 @@ env.__class__.ConfigureForObjectiveCPP = configure_for_objective_cpp
|
||||||
env.__class__.RelaxCompilerSettings = relax_compiler_settings
|
env.__class__.RelaxCompilerSettings = relax_compiler_settings
|
||||||
|
|
||||||
if hasCollada:
|
if hasCollada:
|
||||||
env.Append(CPPDEFINES = [['MTS_HAS_COLLADA', 1]] )
|
env.Append(CPPDEFINES = [['MTS_HAS_COLLADA', 1]])
|
||||||
|
|
||||||
env.SConsignFile()
|
env.SConsignFile()
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ Priority: optional
|
||||||
Maintainer: Wenzel Jakob <wenzel@cs.cornell.edu>
|
Maintainer: Wenzel Jakob <wenzel@cs.cornell.edu>
|
||||||
Build-Depends: debhelper (>= 7), build-essential, scons, qt4-dev-tools,
|
Build-Depends: debhelper (>= 7), build-essential, scons, qt4-dev-tools,
|
||||||
libpng12-dev, libjpeg-dev, libilmbase-dev, libopenexr-dev,
|
libpng12-dev, libjpeg-dev, libilmbase-dev, libopenexr-dev,
|
||||||
libxerces-c-dev, libboost-dev, libglewmx1.5-dev, libxxf86vm-dev,
|
libxerces-c-dev, libboost-dev, libglewmx-dev, libxxf86vm-dev,
|
||||||
collada-dom-dev, libboost-system-dev, libboost-filesystem-dev,
|
collada-dom-dev, libboost-system-dev, libboost-filesystem-dev,
|
||||||
libboost-python-dev, libboost-thread-dev, libgl1-mesa-dev,
|
libboost-python-dev, libboost-thread-dev, libgl1-mesa-dev,
|
||||||
libglu1-mesa-dev, pkg-config, libeigen3-dev
|
libglu1-mesa-dev, pkg-config, libeigen3-dev
|
||||||
|
@ -24,7 +24,7 @@ Description: Mitsuba renderer
|
||||||
Package: mitsuba-dev
|
Package: mitsuba-dev
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Depends: qt4-dev-tools, libpng12-dev, libjpeg-dev, libilmbase-dev,
|
Depends: qt4-dev-tools, libpng12-dev, libjpeg-dev, libilmbase-dev,
|
||||||
libopenexr-dev, libxerces-c-dev, libboost-dev, libglewmx1.5-dev,
|
libopenexr-dev, libxerces-c-dev, libboost-dev, libglewmx-dev,
|
||||||
libxxf86vm-dev, collada-dom-dev, libboost-system-dev,
|
libxxf86vm-dev, collada-dom-dev, libboost-system-dev,
|
||||||
libboost-filesystem-dev, libboost-python-dev, libboost-thread-dev,
|
libboost-filesystem-dev, libboost-python-dev, libboost-thread-dev,
|
||||||
libeigen3-dev, mitsuba
|
libeigen3-dev, mitsuba
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
#include <mitsuba/core/constants.h>
|
#include <mitsuba/core/constants.h>
|
||||||
#include <mitsuba/core/fwd.h>
|
#include <mitsuba/core/fwd.h>
|
||||||
#include <mitsuba/render/fwd.h>
|
#include <mitsuba/render/fwd.h>
|
||||||
#include <mitsuba/core/stl.h>
|
#include <mitsuba/core/math.h>
|
||||||
#include <mitsuba/core/object.h>
|
#include <mitsuba/core/object.h>
|
||||||
#include <mitsuba/core/ref.h>
|
#include <mitsuba/core/ref.h>
|
||||||
#include <mitsuba/core/tls.h>
|
#include <mitsuba/core/tls.h>
|
||||||
|
|
|
@ -2,11 +2,18 @@
|
||||||
\subsection{Subsurface scattering models}
|
\subsection{Subsurface scattering models}
|
||||||
\label{sec:subsurface}
|
\label{sec:subsurface}
|
||||||
There are two ways of simulating subsurface scattering within Mitsuba:
|
There are two ways of simulating subsurface scattering within Mitsuba:
|
||||||
participating media and subsurface scattering models. The latter are described
|
participating media and subsurface scattering models.
|
||||||
in this section and can be thought of as a first-order approximation of the
|
|
||||||
former. For this reason, subsurface scattering models should be preferred when
|
\begin{description}
|
||||||
visually appealing output should be generated quickly and the demands on
|
\item[Subsurface scattering models:] Described in this section. These can be thought
|
||||||
physical realism are secondary.
|
of as a first-order approximation of what happens inside a participating medium.
|
||||||
|
They are preferable when visually appealing output should be generated
|
||||||
|
\emph{quickly} and the demands on accuracy are secondary.
|
||||||
|
At the moment, there is only one subsurface scattering model (the
|
||||||
|
\pluginref{dipole}), which is described on the next page.
|
||||||
|
\item[Participating media:] Described in Section~\ref{sec:media}. When modeling
|
||||||
|
subsurface scattering using a participating medium, Mitsuba performs a \emph{full}
|
||||||
|
radiative transport simulation, which correctly accounts for all scattering events.
|
||||||
|
This is more accurate but generally significantly slower.
|
||||||
|
\end{description}
|
||||||
|
|
||||||
At the moment, there is only one subsurface scattering model (the
|
|
||||||
\pluginref{dipole}), which is described on the next page.
|
|
||||||
|
|
|
@ -393,17 +393,8 @@ public:
|
||||||
/// Draw a rectangle with the specified position and size
|
/// Draw a rectangle with the specified position and size
|
||||||
void drawRect(const Point2i &offset, const Vector2i &size, const Spectrum &value);
|
void drawRect(const Point2i &offset, const Vector2i &size, const Spectrum &value);
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Color balancing: apply the given scale factors to the
|
|
||||||
* red, green, and blue channels of the image
|
|
||||||
*
|
|
||||||
* When the image is not an \c EFloat16, \c EFloat32, or
|
|
||||||
* \c EFloat64-based RGB/RGBA image, the function throws an exception
|
|
||||||
*/
|
|
||||||
void colorBalance(Float r, Float g, Float b);
|
|
||||||
|
|
||||||
/// Draw a filled rectangle with the specified position and size
|
/// Draw a filled rectangle with the specified position and size
|
||||||
void fill(const Point2i &offset, const Vector2i &size, const Spectrum &value);
|
void fillRect(Point2i offset, Vector2i size, const Spectrum &value);
|
||||||
|
|
||||||
/// Bitmap equality operator (useful for unit-tests etc.)
|
/// Bitmap equality operator (useful for unit-tests etc.)
|
||||||
bool operator==(const Bitmap &bitmap) const;
|
bool operator==(const Bitmap &bitmap) const;
|
||||||
|
@ -699,7 +690,43 @@ public:
|
||||||
* use different component formats or channels, or when the
|
* use different component formats or channels, or when the
|
||||||
* component format is \ref EBitmask.
|
* component format is \ref EBitmask.
|
||||||
*/
|
*/
|
||||||
void accumulate(const Bitmap *bitmap, const Point2i &offset);
|
void accumulate(const Bitmap *bitmap, Point2i sourceOffset,
|
||||||
|
Point2i targetOffset, Vector2i size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Color balancing: apply the given scale factors to the
|
||||||
|
* red, green, and blue channels of the image
|
||||||
|
*
|
||||||
|
* When the image is not an \c EFloat16, \c EFloat32, or
|
||||||
|
* \c EFloat64-based RGB/RGBA image, the function throws an exception
|
||||||
|
*/
|
||||||
|
void colorBalance(Float r, Float g, Float b);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply a color transformation matrix to the contents of the bitmap
|
||||||
|
*
|
||||||
|
* The implementation assumes that the contents have the
|
||||||
|
* RGB, RGBA, XYZ, or XYZA pixel format and a floating point
|
||||||
|
* component format.
|
||||||
|
*/
|
||||||
|
void applyMatrix(Float matrix[3][3]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Accumulate the contents of another bitmap into the
|
||||||
|
* region of the specified offset
|
||||||
|
*
|
||||||
|
* This convenience function calls the main <tt>accumulate()</tt>
|
||||||
|
* implementation with <tt>size</tt> set to <tt>bitmap->getSize()</tt>
|
||||||
|
* and <tt>sourceOffset</tt> set to zero. Out-of-bounds regions are
|
||||||
|
* ignored. It is assumed that <tt>bitmap != this</tt>.
|
||||||
|
*
|
||||||
|
* \remark This function throws an exception when the bitmaps
|
||||||
|
* use different component formats or channels, or when the
|
||||||
|
* component format is \ref EBitmask.
|
||||||
|
*/
|
||||||
|
inline void accumulate(const Bitmap *bitmap, Point2i targetOffset) {
|
||||||
|
accumulate(bitmap, Point2i(0), targetOffset, bitmap->getSize());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Up- or down-sample this image to a different resolution
|
* \brief Up- or down-sample this image to a different resolution
|
||||||
|
|
|
@ -189,6 +189,55 @@ extern MTS_EXPORT_CORE void __mts_set_appdefaults();
|
||||||
#define MTS_AUTORELEASE_BEGIN()
|
#define MTS_AUTORELEASE_BEGIN()
|
||||||
#define MTS_AUTORELEASE_END()
|
#define MTS_AUTORELEASE_END()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MTS_NAMESPACE_END
|
MTS_NAMESPACE_END
|
||||||
|
|
||||||
|
|
||||||
|
/// \cond
|
||||||
|
// Try to make MSVC++ behave a bit more like C++
|
||||||
|
// with an underlying C99 implementation
|
||||||
|
// (and dn't include this in the documentation)
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
|
#define snprintf _snprintf
|
||||||
|
#define vsnprintf _vsnprintf
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
|
||||||
|
inline char tolower(char c) {
|
||||||
|
return ::tolower(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline char toupper(char c) {
|
||||||
|
return ::toupper(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool isnan(float f) {
|
||||||
|
return _isnan(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool isnan(double f) {
|
||||||
|
return _isnan(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool isfinite(float f) {
|
||||||
|
return _finite(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool isfinite(double f) {
|
||||||
|
return _finite(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool isinf(float f) {
|
||||||
|
return !_finite(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool isinf(double f) {
|
||||||
|
return !_finite(f);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __MITSUBA_CORE_PLATFORM_H_ */
|
#endif /* __MITSUBA_CORE_PLATFORM_H_ */
|
||||||
|
|
|
@ -493,6 +493,14 @@ public:
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Component-wise square root
|
||||||
|
inline TSpectrum safe_sqrt() const {
|
||||||
|
TSpectrum value;
|
||||||
|
for (int i=0; i<N; i++)
|
||||||
|
value.s[i] = math::safe_sqrt(s[i]);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
/// Component-wise exponentation
|
/// Component-wise exponentation
|
||||||
inline TSpectrum exp() const {
|
inline TSpectrum exp() const {
|
||||||
TSpectrum value;
|
TSpectrum value;
|
||||||
|
|
|
@ -20,90 +20,6 @@
|
||||||
#if !defined(__MITSUBA_CORE_STL_H_)
|
#if !defined(__MITSUBA_CORE_STL_H_)
|
||||||
#define __MITSUBA_CORE_STL_H_
|
#define __MITSUBA_CORE_STL_H_
|
||||||
|
|
||||||
/* Include some SGI STL extensions, which might be missing */
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#include <ext/functional>
|
|
||||||
using __gnu_cxx::select2nd;
|
|
||||||
using __gnu_cxx::compose1;
|
|
||||||
#else
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
/// \cond
|
|
||||||
// (Don't include in the documentation)
|
|
||||||
namespace std {
|
|
||||||
template <class _Pair> struct _Select1st : public unary_function<_Pair, typename _Pair::first_type> {
|
|
||||||
const typename _Pair::first_type& operator()(const _Pair& __x) const {
|
|
||||||
return __x.first;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class _Pair> struct _Select2nd : public unary_function<_Pair, typename _Pair::second_type> {
|
|
||||||
const typename _Pair::second_type& operator()(const _Pair& __x) const {
|
|
||||||
return __x.second;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class _Pair> struct select1st : public _Select1st<_Pair> {};
|
|
||||||
template <class _Pair> struct select2nd : public _Select2nd<_Pair> {};
|
|
||||||
|
|
||||||
template <class _Operation1, class _Operation2> class unary_compose : public unary_function<typename _Operation2::argument_type, typename _Operation1::result_type> {
|
|
||||||
protected:
|
|
||||||
_Operation1 _M_fn1;
|
|
||||||
_Operation2 _M_fn2;
|
|
||||||
public:
|
|
||||||
unary_compose(const _Operation1& __x, const _Operation2& __y) : _M_fn1(__x), _M_fn2(__y) {}
|
|
||||||
typename _Operation1::result_type operator()(const typename _Operation2::argument_type& __x) const {
|
|
||||||
return _M_fn1(_M_fn2(__x));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class _Operation1, class _Operation2> inline unary_compose<_Operation1,_Operation2> compose1(const _Operation1& __fn1, const _Operation2& __fn2) {
|
|
||||||
return unary_compose<_Operation1,_Operation2>(__fn1, __fn2);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#include <float.h>
|
|
||||||
|
|
||||||
#define snprintf _snprintf
|
|
||||||
#define vsnprintf _vsnprintf
|
|
||||||
|
|
||||||
inline char tolower(char c) {
|
|
||||||
return ::tolower(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline char toupper(char c) {
|
|
||||||
return ::toupper(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool isnan(float f) {
|
|
||||||
return _isnan(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool isnan(double f) {
|
|
||||||
return _isnan(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool isfinite(float f) {
|
|
||||||
return _finite(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool isfinite(double f) {
|
|
||||||
return _finite(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool isinf(float f) {
|
|
||||||
return !_finite(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool isinf(double f) {
|
|
||||||
return !_finite(f);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
using std::select2nd;
|
|
||||||
using std::compose1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace mitsuba {
|
namespace mitsuba {
|
||||||
namespace math {
|
namespace math {
|
||||||
#if defined(__LINUX__) && defined(__x86_64__)
|
#if defined(__LINUX__) && defined(__x86_64__)
|
||||||
|
|
|
@ -507,22 +507,99 @@ inline Float fresnelDielectricExt(Float cosThetaI, Float eta) { Float cosThetaT;
|
||||||
return fresnelDielectricExt(cosThetaI, cosThetaT, eta); }
|
return fresnelDielectricExt(cosThetaI, cosThetaT, eta); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Calculates the unpolarized fresnel reflection coefficient
|
* \brief Calculates the unpolarized Fresnel reflection coefficient
|
||||||
* at a planar interface between vacuum and a conductor.
|
* at a planar interface having a complex-valued relative index of
|
||||||
|
* refraction (approximate scalar version)
|
||||||
|
*
|
||||||
|
* The implementation of this function relies on a simplified expression
|
||||||
|
* that becomes increasingly accurate as k grows.
|
||||||
|
*
|
||||||
|
* The name of this function is a slight misnomer, since it supports
|
||||||
|
* the general case of a complex-valued relative index of refraction
|
||||||
|
* (rather than being restricted to conductors)
|
||||||
*
|
*
|
||||||
* \param cosThetaI
|
* \param cosThetaI
|
||||||
* Cosine of the angle between the normal and the incident ray
|
* Cosine of the angle between the normal and the incident ray
|
||||||
* \param eta
|
* \param eta
|
||||||
* Real refractive index (wavelength-dependent)
|
* Relative refractive index (real component)
|
||||||
* \param k
|
* \param k
|
||||||
* Imaginary refractive index (wavelength-dependent)
|
* Relative refractive index (imaginary component)
|
||||||
* \ingroup libpython
|
* \ingroup libpython
|
||||||
*/
|
*/
|
||||||
extern MTS_EXPORT_CORE Spectrum fresnelConductor(Float cosThetaI,
|
extern MTS_EXPORT_CORE Float fresnelConductorApprox(Float cosThetaI,
|
||||||
|
Float eta, Float k);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Calculates the unpolarized Fresnel reflection coefficient
|
||||||
|
* at a planar interface having a complex-valued relative index of
|
||||||
|
* refraction (approximate vectorized version)
|
||||||
|
*
|
||||||
|
* The implementation of this function relies on a simplified expression
|
||||||
|
* that becomes increasingly accurate as k grows.
|
||||||
|
*
|
||||||
|
* The name of this function is a slight misnomer, since it supports
|
||||||
|
* the general case of a complex-valued relative index of refraction
|
||||||
|
* (rather than being restricted to conductors)
|
||||||
|
*
|
||||||
|
* \param cosThetaI
|
||||||
|
* Cosine of the angle between the normal and the incident ray
|
||||||
|
* \param eta
|
||||||
|
* Relative refractive index (real component)
|
||||||
|
* \param k
|
||||||
|
* Relative refractive index (imaginary component)
|
||||||
|
* \ingroup libpython
|
||||||
|
*/
|
||||||
|
extern MTS_EXPORT_CORE Spectrum fresnelConductorApprox(Float cosThetaI,
|
||||||
const Spectrum &eta, const Spectrum &k);
|
const Spectrum &eta, const Spectrum &k);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Calculates the diffuse unpolarized fresnel reflectance of
|
* \brief Calculates the unpolarized Fresnel reflection coefficient
|
||||||
|
* at a planar interface having a complex-valued relative index of
|
||||||
|
* refraction (accurate scalar version)
|
||||||
|
*
|
||||||
|
* The implementation of this function computes the exact unpolarized
|
||||||
|
* Fresnel reflectance for a complex index of refraction change.
|
||||||
|
*
|
||||||
|
* The name of this function is a slight misnomer, since it supports
|
||||||
|
* the general case of a complex-valued relative index of refraction
|
||||||
|
* (rather than being restricted to conductors)
|
||||||
|
*
|
||||||
|
* \param cosThetaI
|
||||||
|
* Cosine of the angle between the normal and the incident ray
|
||||||
|
* \param eta
|
||||||
|
* Relative refractive index (real component)
|
||||||
|
* \param k
|
||||||
|
* Relative refractive index (imaginary component)
|
||||||
|
* \ingroup libpython
|
||||||
|
*/
|
||||||
|
extern MTS_EXPORT_CORE Float fresnelConductorExact(Float cosThetaI,
|
||||||
|
Float eta, Float k);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Calculates the unpolarized Fresnel reflection coefficient
|
||||||
|
* at a planar interface having a complex-valued relative index of
|
||||||
|
* refraction (accurate vectorized version)
|
||||||
|
*
|
||||||
|
* The implementation of this function computes the exact unpolarized
|
||||||
|
* Fresnel reflectance for a complex index of refraction change.
|
||||||
|
*
|
||||||
|
* The name of this function is a slight misnomer, since it supports
|
||||||
|
* the general case of a complex-valued relative index of refraction
|
||||||
|
* (rather than being restricted to conductors)
|
||||||
|
*
|
||||||
|
* \param cosThetaI
|
||||||
|
* Cosine of the angle between the normal and the incident ray
|
||||||
|
* \param eta
|
||||||
|
* Relative refractive index (real component)
|
||||||
|
* \param k
|
||||||
|
* Relative refractive index (imaginary component)
|
||||||
|
* \ingroup libpython
|
||||||
|
*/
|
||||||
|
extern MTS_EXPORT_CORE Spectrum fresnelConductorExact(Float cosThetaI,
|
||||||
|
const Spectrum &eta, const Spectrum &k);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Calculates the diffuse unpolarized Fresnel reflectance of
|
||||||
* a dielectric material (sometimes referred to as "Fdr").
|
* a dielectric material (sometimes referred to as "Fdr").
|
||||||
*
|
*
|
||||||
* This value quantifies what fraction of diffuse incident illumination
|
* This value quantifies what fraction of diffuse incident illumination
|
||||||
|
|
|
@ -76,12 +76,22 @@ public:
|
||||||
/// Allocate memory for a certain font
|
/// Allocate memory for a certain font
|
||||||
Font(EFont font);
|
Font(EFont font);
|
||||||
|
|
||||||
|
/// Draw text to the specified bitmap
|
||||||
|
void drawText(Bitmap *dest, Point2i pos, const std::string &text) const;
|
||||||
|
|
||||||
|
/// Compute the size covered by the given string when rendered using this font
|
||||||
|
Vector2i getSize(const std::string &text) const;
|
||||||
|
|
||||||
/// Upload the font to the GPU
|
/// Upload the font to the GPU
|
||||||
void init(Renderer *renderer);
|
void init(Renderer *renderer);
|
||||||
|
|
||||||
/// Free the GPU memory
|
/// Free the GPU memory
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
|
/// Convert the underlying bitmap to a different pixel format
|
||||||
|
void convert(Bitmap::EPixelFormat pixelFormat,
|
||||||
|
Bitmap::EComponentFormat componentFormat, Float gamma);
|
||||||
|
|
||||||
/// Return the name of this font
|
/// Return the name of this font
|
||||||
inline const std::string &getName() const { return m_name; }
|
inline const std::string &getName() const { return m_name; }
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,9 @@ public:
|
||||||
/// Serialize to a binary data stream
|
/// Serialize to a binary data stream
|
||||||
virtual void serialize(Stream *stream, InstanceManager *manager) const;
|
virtual void serialize(Stream *stream, InstanceManager *manager) const;
|
||||||
|
|
||||||
|
/// Return the underlying bitmap representation (if any)
|
||||||
|
virtual ref<Bitmap> getBitmap() const;
|
||||||
|
|
||||||
MTS_DECLARE_CLASS()
|
MTS_DECLARE_CLASS()
|
||||||
protected:
|
protected:
|
||||||
Texture(const Properties &props);
|
Texture(const Properties &props);
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <mitsuba/core/fresolver.h>
|
#include <mitsuba/core/fresolver.h>
|
||||||
#include <mitsuba/hw/basicshader.h>
|
#include <mitsuba/hw/basicshader.h>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#include "ior.h"
|
||||||
|
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
@ -29,11 +30,12 @@ MTS_NAMESPACE_BEGIN
|
||||||
* \parameters{
|
* \parameters{
|
||||||
* \parameter{material}{\String}{Name of a material preset, see
|
* \parameter{material}{\String}{Name of a material preset, see
|
||||||
* \tblref{conductor-iors}.\!\default{\texttt{Cu} / copper}}
|
* \tblref{conductor-iors}.\!\default{\texttt{Cu} / copper}}
|
||||||
* \parameter{eta}{\Spectrum}{Real part of the material's index
|
* \parameter{eta, k}{\Spectrum}{Real and imaginary components of the material's index of
|
||||||
* of refraction \default{based on the value of \texttt{material}}}
|
* refraction \default{based on the value of \texttt{material}}}
|
||||||
* \parameter{k}{\Spectrum}{Imaginary part of the material's index of
|
* \parameter{extEta}{\Float\Or\String}{
|
||||||
* refraction, also known as absorption coefficient.
|
* Real-valued index of refraction of the surrounding dielectric,
|
||||||
* \default{based on the value of \texttt{material}}}
|
* or a material name of a dielectric \default{\code{air}}
|
||||||
|
* }
|
||||||
* \parameter{specular\showbreak Reflectance}{\Spectrum\Or\Texture}{Optional
|
* \parameter{specular\showbreak Reflectance}{\Spectrum\Or\Texture}{Optional
|
||||||
* factor that can be used to modulate the specular reflection component. Note
|
* factor that can be used to modulate the specular reflection component. Note
|
||||||
* that for physical realism, this parameter should never be touched. \default{1.0}}
|
* that for physical realism, this parameter should never be touched. \default{1.0}}
|
||||||
|
@ -154,21 +156,23 @@ public:
|
||||||
m_specularReflectance = new ConstantSpectrumTexture(
|
m_specularReflectance = new ConstantSpectrumTexture(
|
||||||
props.getSpectrum("specularReflectance", Spectrum(1.0f)));
|
props.getSpectrum("specularReflectance", Spectrum(1.0f)));
|
||||||
|
|
||||||
std::string material = props.getString("material", "Cu");
|
std::string materialName = props.getString("material", "Cu");
|
||||||
|
|
||||||
Spectrum materialEta, materialK;
|
Spectrum intEta, intK;
|
||||||
if (boost::to_lower_copy(material) == "none") {
|
if (boost::to_lower_copy(materialName) == "none") {
|
||||||
materialEta = Spectrum(0.0f);
|
intEta = Spectrum(0.0f);
|
||||||
materialK = Spectrum(1.0f);
|
intK = Spectrum(1.0f);
|
||||||
} else {
|
} else {
|
||||||
materialEta.fromContinuousSpectrum(InterpolatedSpectrum(
|
intEta.fromContinuousSpectrum(InterpolatedSpectrum(
|
||||||
fResolver->resolve("data/ior/" + material + ".eta.spd")));
|
fResolver->resolve("data/ior/" + materialName + ".eta.spd")));
|
||||||
materialK.fromContinuousSpectrum(InterpolatedSpectrum(
|
intK.fromContinuousSpectrum(InterpolatedSpectrum(
|
||||||
fResolver->resolve("data/ior/" + material + ".k.spd")));
|
fResolver->resolve("data/ior/" + materialName + ".k.spd")));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_eta = props.getSpectrum("eta", materialEta);
|
Float extEta = lookupIOR(props, "extEta", "air");
|
||||||
m_k = props.getSpectrum("k", materialK);
|
|
||||||
|
m_eta = props.getSpectrum("eta", intEta) / extEta;
|
||||||
|
m_k = props.getSpectrum("k", intK) / extEta;
|
||||||
}
|
}
|
||||||
|
|
||||||
SmoothConductor(Stream *stream, InstanceManager *manager)
|
SmoothConductor(Stream *stream, InstanceManager *manager)
|
||||||
|
@ -229,7 +233,7 @@ public:
|
||||||
return Spectrum(0.0f);
|
return Spectrum(0.0f);
|
||||||
|
|
||||||
return m_specularReflectance->eval(bRec.its) *
|
return m_specularReflectance->eval(bRec.its) *
|
||||||
fresnelConductor(Frame::cosTheta(bRec.wi), m_eta, m_k);
|
fresnelConductorExact(Frame::cosTheta(bRec.wi), m_eta, m_k);
|
||||||
}
|
}
|
||||||
|
|
||||||
Float pdf(const BSDFSamplingRecord &bRec, EMeasure measure) const {
|
Float pdf(const BSDFSamplingRecord &bRec, EMeasure measure) const {
|
||||||
|
@ -260,7 +264,7 @@ public:
|
||||||
bRec.eta = 1.0f;
|
bRec.eta = 1.0f;
|
||||||
|
|
||||||
return m_specularReflectance->eval(bRec.its) *
|
return m_specularReflectance->eval(bRec.its) *
|
||||||
fresnelConductor(Frame::cosTheta(bRec.wi), m_eta, m_k);
|
fresnelConductorExact(Frame::cosTheta(bRec.wi), m_eta, m_k);
|
||||||
}
|
}
|
||||||
|
|
||||||
Spectrum sample(BSDFSamplingRecord &bRec, Float &pdf, const Point2 &sample) const {
|
Spectrum sample(BSDFSamplingRecord &bRec, Float &pdf, const Point2 &sample) const {
|
||||||
|
@ -277,7 +281,7 @@ public:
|
||||||
pdf = 1;
|
pdf = 1;
|
||||||
|
|
||||||
return m_specularReflectance->eval(bRec.its) *
|
return m_specularReflectance->eval(bRec.its) *
|
||||||
fresnelConductor(Frame::cosTheta(bRec.wi), m_eta, m_k);
|
fresnelConductorExact(Frame::cosTheta(bRec.wi), m_eta, m_k);
|
||||||
}
|
}
|
||||||
|
|
||||||
Float getRoughness(const Intersection &its, int component) const {
|
Float getRoughness(const Intersection &its, int component) const {
|
||||||
|
@ -320,7 +324,7 @@ public:
|
||||||
m_specularReflectanceShader = renderer->registerShaderForResource(m_specularReflectance.get());
|
m_specularReflectanceShader = renderer->registerShaderForResource(m_specularReflectance.get());
|
||||||
|
|
||||||
/* Compute the reflectance at perpendicular incidence */
|
/* Compute the reflectance at perpendicular incidence */
|
||||||
m_R0 = fresnelConductor(1.0f, eta, k);
|
m_R0 = fresnelConductorExact(1.0f, eta, k);
|
||||||
|
|
||||||
m_alpha = 0.4f;
|
m_alpha = 0.4f;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <mitsuba/render/bsdf.h>
|
#include <mitsuba/render/bsdf.h>
|
||||||
#include <mitsuba/hw/basicshader.h>
|
#include <mitsuba/hw/basicshader.h>
|
||||||
#include "microfacet.h"
|
#include "microfacet.h"
|
||||||
|
#include "ior.h"
|
||||||
|
|
||||||
MTS_NAMESPACE_BEGIN
|
MTS_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
@ -32,15 +33,15 @@ MTS_NAMESPACE_BEGIN
|
||||||
* used to model the surface roughness.
|
* used to model the surface roughness.
|
||||||
* \begin{enumerate}[(i)]
|
* \begin{enumerate}[(i)]
|
||||||
* \item \code{beckmann}: Physically-based distribution derived from
|
* \item \code{beckmann}: Physically-based distribution derived from
|
||||||
* Gaussian random surfaces. This is the default.
|
* Gaussian random surfaces. This is the default.\vspace{-1mm}
|
||||||
* \item \code{ggx}: New distribution proposed by
|
* \item \code{ggx}: New distribution proposed by
|
||||||
* Walter et al. \cite{Walter07Microfacet}, which is meant to better handle
|
* Walter et al. \cite{Walter07Microfacet}, which is meant to better handle
|
||||||
* the long tails observed in measurements of ground surfaces.
|
* the long tails observed in measurements of ground surfaces.
|
||||||
* Renderings with this distribution may converge slowly.
|
* Renderings with this distribution may converge slowly.\vspace{-1mm}
|
||||||
* \item \code{phong}: Classical $\cos^p\theta$ distribution.
|
* \item \code{phong}: Classical $\cos^p\theta$ distribution.
|
||||||
* Due to the underlying microfacet theory,
|
* Due to the underlying microfacet theory,
|
||||||
* the use of this distribution here leads to more realistic
|
* the use of this distribution here leads to more realistic
|
||||||
* behavior than the separately available \pluginref{phong} plugin.
|
* behavior than the separately available \pluginref{phong} plugin.\vspace{-1mm}
|
||||||
* \item \code{as}: Anisotropic Phong-style microfacet distribution proposed by
|
* \item \code{as}: Anisotropic Phong-style microfacet distribution proposed by
|
||||||
* Ashikhmin and Shirley \cite{Ashikhmin2005Anisotropic}.\vspace{-3mm}
|
* Ashikhmin and Shirley \cite{Ashikhmin2005Anisotropic}.\vspace{-3mm}
|
||||||
* \end{enumerate}
|
* \end{enumerate}
|
||||||
|
@ -59,11 +60,12 @@ MTS_NAMESPACE_BEGIN
|
||||||
* }
|
* }
|
||||||
* \parameter{material}{\String}{Name of a material preset, see
|
* \parameter{material}{\String}{Name of a material preset, see
|
||||||
* \tblref{conductor-iors}.\!\default{\texttt{Cu} / copper}}
|
* \tblref{conductor-iors}.\!\default{\texttt{Cu} / copper}}
|
||||||
* \parameter{eta}{\Spectrum}{Real part of the material's index
|
* \parameter{eta, k}{\Spectrum}{Real and imaginary components of the material's index of
|
||||||
* of refraction \default{based on the value of \texttt{material}}}
|
* refraction \default{based on the value of \texttt{material}}}
|
||||||
* \parameter{k}{\Spectrum}{Imaginary part of the material's index of
|
* \parameter{extEta}{\Float\Or\String}{
|
||||||
* refraction (the absorption coefficient).
|
* Real-valued index of refraction of the surrounding dielectric,
|
||||||
* \default{based on \texttt{material}}}
|
* or a material name of a dielectric \default{\code{air}}
|
||||||
|
* }
|
||||||
* \parameter{specular\showbreak Reflectance}{\Spectrum\Or\Texture}{Optional
|
* \parameter{specular\showbreak Reflectance}{\Spectrum\Or\Texture}{Optional
|
||||||
* factor that can be used to modulate the specular reflection component. Note
|
* factor that can be used to modulate the specular reflection component. Note
|
||||||
* that for physical realism, this parameter should never be touched. \default{1.0}}
|
* that for physical realism, this parameter should never be touched. \default{1.0}}
|
||||||
|
@ -158,21 +160,23 @@ public:
|
||||||
m_specularReflectance = new ConstantSpectrumTexture(
|
m_specularReflectance = new ConstantSpectrumTexture(
|
||||||
props.getSpectrum("specularReflectance", Spectrum(1.0f)));
|
props.getSpectrum("specularReflectance", Spectrum(1.0f)));
|
||||||
|
|
||||||
std::string material = props.getString("material", "Cu");
|
std::string materialName = props.getString("material", "Cu");
|
||||||
Spectrum materialEta, materialK;
|
|
||||||
|
|
||||||
if (boost::to_lower_copy(material) == "none") {
|
Spectrum intEta, intK;
|
||||||
materialEta = Spectrum(0.0f);
|
if (boost::to_lower_copy(materialName) == "none") {
|
||||||
materialK = Spectrum(1.0f);
|
intEta = Spectrum(0.0f);
|
||||||
|
intK = Spectrum(1.0f);
|
||||||
} else {
|
} else {
|
||||||
materialEta.fromContinuousSpectrum(InterpolatedSpectrum(
|
intEta.fromContinuousSpectrum(InterpolatedSpectrum(
|
||||||
fResolver->resolve("data/ior/" + material + ".eta.spd")));
|
fResolver->resolve("data/ior/" + materialName + ".eta.spd")));
|
||||||
materialK.fromContinuousSpectrum(InterpolatedSpectrum(
|
intK.fromContinuousSpectrum(InterpolatedSpectrum(
|
||||||
fResolver->resolve("data/ior/" + material + ".k.spd")));
|
fResolver->resolve("data/ior/" + materialName + ".k.spd")));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_eta = props.getSpectrum("eta", materialEta);
|
Float extEta = lookupIOR(props, "extEta", "air");
|
||||||
m_k = props.getSpectrum("k", materialK);
|
|
||||||
|
m_eta = props.getSpectrum("eta", intEta) / extEta;
|
||||||
|
m_k = props.getSpectrum("k", intK) / extEta;
|
||||||
|
|
||||||
m_distribution = MicrofacetDistribution(
|
m_distribution = MicrofacetDistribution(
|
||||||
props.getString("distribution", "beckmann")
|
props.getString("distribution", "beckmann")
|
||||||
|
@ -262,7 +266,7 @@ public:
|
||||||
return Spectrum(0.0f);
|
return Spectrum(0.0f);
|
||||||
|
|
||||||
/* Fresnel factor */
|
/* Fresnel factor */
|
||||||
const Spectrum F = fresnelConductor(dot(bRec.wi, H), m_eta, m_k);
|
const Spectrum F = fresnelConductorExact(dot(bRec.wi, H), m_eta, m_k);
|
||||||
|
|
||||||
/* Smith's shadow-masking function */
|
/* Smith's shadow-masking function */
|
||||||
const Float G = m_distribution.G(bRec.wi, bRec.wo, H, alphaU, alphaV);
|
const Float G = m_distribution.G(bRec.wi, bRec.wo, H, alphaU, alphaV);
|
||||||
|
@ -324,7 +328,7 @@ public:
|
||||||
if (Frame::cosTheta(bRec.wo) <= 0)
|
if (Frame::cosTheta(bRec.wo) <= 0)
|
||||||
return Spectrum(0.0f);
|
return Spectrum(0.0f);
|
||||||
|
|
||||||
const Spectrum F = fresnelConductor(dot(bRec.wi, m),
|
const Spectrum F = fresnelConductorExact(dot(bRec.wi, m),
|
||||||
m_eta, m_k);
|
m_eta, m_k);
|
||||||
|
|
||||||
Float numerator = m_distribution.eval(m, alphaU, alphaV)
|
Float numerator = m_distribution.eval(m, alphaU, alphaV)
|
||||||
|
@ -367,7 +371,7 @@ public:
|
||||||
if (Frame::cosTheta(bRec.wo) <= 0)
|
if (Frame::cosTheta(bRec.wo) <= 0)
|
||||||
return Spectrum(0.0f);
|
return Spectrum(0.0f);
|
||||||
|
|
||||||
const Spectrum F = fresnelConductor(dot(bRec.wi, m),
|
const Spectrum F = fresnelConductorExact(dot(bRec.wi, m),
|
||||||
m_eta, m_k);
|
m_eta, m_k);
|
||||||
|
|
||||||
Float numerator = m_distribution.eval(m, alphaU, alphaV)
|
Float numerator = m_distribution.eval(m, alphaU, alphaV)
|
||||||
|
@ -460,7 +464,7 @@ public:
|
||||||
m_alphaVShader = renderer->registerShaderForResource(m_alphaV.get());
|
m_alphaVShader = renderer->registerShaderForResource(m_alphaV.get());
|
||||||
|
|
||||||
/* Compute the reflectance at perpendicular incidence */
|
/* Compute the reflectance at perpendicular incidence */
|
||||||
m_R0 = fresnelConductor(1.0f, eta, k);
|
m_R0 = fresnelConductorExact(1.0f, eta, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isComplete() const {
|
bool isComplete() const {
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <mitsuba/core/fstream.h>
|
#include <mitsuba/core/fstream.h>
|
||||||
#include <mitsuba/core/bitmap.h>
|
#include <mitsuba/core/bitmap.h>
|
||||||
#include <mitsuba/core/statistics.h>
|
#include <mitsuba/core/statistics.h>
|
||||||
|
#include <mitsuba/hw/font.h>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include "banner.h"
|
#include "banner.h"
|
||||||
|
|
||||||
|
@ -114,7 +115,33 @@ MTS_NAMESPACE_BEGIN
|
||||||
* <boolean name="banner" value="false"/>
|
* <boolean name="banner" value="false"/>
|
||||||
* </film>
|
* </film>
|
||||||
* \end{xml}
|
* \end{xml}
|
||||||
|
*
|
||||||
|
* \subsubsection*{Annotations:}
|
||||||
|
* \label{sec:film-annotations}
|
||||||
|
* The \pluginref{ldrfilm} and \pluginref{hdrfilm} plugins support an additional
|
||||||
|
* feature referred to as \emph{annotations}, which can be quite useful under
|
||||||
|
* certain circumstances.
|
||||||
|
*
|
||||||
|
* Annotations are used to embed useful information inside a rendered image so
|
||||||
|
* that this information is later available to anyone viewing the image.
|
||||||
|
* Exemplary uses of this feature might be to store the frame or take number,
|
||||||
|
* camera parameters, or other relevant scene information.
|
||||||
|
*
|
||||||
|
* Annotations can either be created by means of a \emph{tag}, which is an entry
|
||||||
|
* in the metadata table of the image file (does not modify the actual image data),
|
||||||
|
* or a \emph{text} label which is ``burned'' into the image.
|
||||||
|
*
|
||||||
|
* The syntax of this looks as follows:
|
||||||
|
*
|
||||||
|
* \begin{xml}
|
||||||
|
* <film type="ldrfilm">
|
||||||
|
* <!-- Create a new metadata entry 'my_tag_name' and set it to the value 'my_tag_value' -->
|
||||||
|
* <string name="tag('my_tag_name')" value="my_tag_value"/>
|
||||||
|
*
|
||||||
|
* <!-- Add the label 'Hello' at the image position X=50, Y=80 -->
|
||||||
|
* <string name="text(50,80)" value="Hello!"/>
|
||||||
|
* </film>
|
||||||
|
* \end{xml}
|
||||||
*/
|
*/
|
||||||
class HDRFilm : public Film {
|
class HDRFilm : public Film {
|
||||||
public:
|
public:
|
||||||
|
@ -204,6 +231,25 @@ public:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> keys = props.getPropertyNames();
|
||||||
|
for (size_t i=0; i<keys.size(); ++i) {
|
||||||
|
std::string key = boost::to_lower_copy(keys[i]);
|
||||||
|
|
||||||
|
if (boost::starts_with(key, "tag('") && boost::ends_with(key, "')")) {
|
||||||
|
m_tags[keys[i].substr(5, key.length()-7)] = props.getString(keys[i]);
|
||||||
|
} else if (boost::starts_with(key, "text(") && boost::ends_with(key, ")")) {
|
||||||
|
std::vector<std::string> args = tokenize(key.substr(5, key.length()-6), " ,");
|
||||||
|
|
||||||
|
if (args.size() != 2)
|
||||||
|
Log(EError, "Text command '%s' has an invalid number of arguments!", key.c_str());
|
||||||
|
|
||||||
|
Annotation annotation;
|
||||||
|
annotation.offset = Point2i(atoi(args[0].c_str()), atoi(args[1].c_str()));
|
||||||
|
annotation.text = props.getString(keys[i]);
|
||||||
|
m_annotations.push_back(annotation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_storage = new ImageBlock(Bitmap::ESpectrumAlphaWeight, m_cropSize);
|
m_storage = new ImageBlock(Bitmap::ESpectrumAlphaWeight, m_cropSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,6 +367,23 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_annotations.empty()) {
|
||||||
|
ref<Font> font = new Font(Font::EBitstreamVeraMono14);
|
||||||
|
font->convert(bitmap->getPixelFormat(), bitmap->getComponentFormat(), 1.0f);
|
||||||
|
|
||||||
|
for (size_t i=0; i<m_annotations.size(); ++i) {
|
||||||
|
const Point2i &offset = m_annotations[i].offset;
|
||||||
|
const std::string &text = m_annotations[i].text;
|
||||||
|
Vector2i size = font->getSize(text);
|
||||||
|
bitmap->fillRect(offset-Vector2i(4, 4), size + Vector2i(8, 8), Spectrum(0.0f));
|
||||||
|
font->drawText(bitmap, offset, text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::map<std::string, std::string>::const_iterator it = m_tags.begin();
|
||||||
|
it != m_tags.end(); ++it)
|
||||||
|
bitmap->getMetadata()[it->first] = it->second;
|
||||||
|
|
||||||
fs::path filename = m_destFile;
|
fs::path filename = m_destFile;
|
||||||
std::string extension = boost::to_lower_copy(filename.extension().string());
|
std::string extension = boost::to_lower_copy(filename.extension().string());
|
||||||
std::string properExtension = (m_fileFormat == Bitmap::EOpenEXR) ? ".exr" : ".rgbe";
|
std::string properExtension = (m_fileFormat == Bitmap::EOpenEXR) ? ".exr" : ".rgbe";
|
||||||
|
@ -367,6 +430,11 @@ public:
|
||||||
|
|
||||||
MTS_DECLARE_CLASS()
|
MTS_DECLARE_CLASS()
|
||||||
protected:
|
protected:
|
||||||
|
struct Annotation {
|
||||||
|
Point2i offset;
|
||||||
|
std::string text;
|
||||||
|
};
|
||||||
|
|
||||||
Bitmap::EFileFormat m_fileFormat;
|
Bitmap::EFileFormat m_fileFormat;
|
||||||
Bitmap::EPixelFormat m_pixelFormat;
|
Bitmap::EPixelFormat m_pixelFormat;
|
||||||
Bitmap::EComponentFormat m_componentFormat;
|
Bitmap::EComponentFormat m_componentFormat;
|
||||||
|
@ -374,6 +442,9 @@ protected:
|
||||||
bool m_attachLog;
|
bool m_attachLog;
|
||||||
fs::path m_destFile;
|
fs::path m_destFile;
|
||||||
ref<ImageBlock> m_storage;
|
ref<ImageBlock> m_storage;
|
||||||
|
|
||||||
|
std::vector<Annotation> m_annotations;
|
||||||
|
std::map<std::string, std::string> m_tags;
|
||||||
};
|
};
|
||||||
|
|
||||||
MTS_IMPLEMENT_CLASS_S(HDRFilm, false, Film)
|
MTS_IMPLEMENT_CLASS_S(HDRFilm, false, Film)
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <mitsuba/core/fstream.h>
|
#include <mitsuba/core/fstream.h>
|
||||||
#include <mitsuba/core/bitmap.h>
|
#include <mitsuba/core/bitmap.h>
|
||||||
#include <mitsuba/core/statistics.h>
|
#include <mitsuba/core/statistics.h>
|
||||||
|
#include <mitsuba/hw/font.h>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include "banner.h"
|
#include "banner.h"
|
||||||
|
|
||||||
|
@ -113,6 +114,9 @@ MTS_NAMESPACE_BEGIN
|
||||||
* The RGB values exported by this plugin correspond to the ITU-R Rec. BT. 709-3
|
* The RGB values exported by this plugin correspond to the ITU-R Rec. BT. 709-3
|
||||||
* primaries with a D65 white point. When $\texttt{gamma}$ is set to $\code{-1}$ (the default),
|
* primaries with a D65 white point. When $\texttt{gamma}$ is set to $\code{-1}$ (the default),
|
||||||
* the output is in the sRGB color space and will display as intended on compatible devices.
|
* the output is in the sRGB color space and will display as intended on compatible devices.
|
||||||
|
*
|
||||||
|
* Note that this plugin supports render-time \emph{annotations}, which
|
||||||
|
* are described on page~\pageref{sec:film-annotations}.
|
||||||
*/
|
*/
|
||||||
class LDRFilm : public Film {
|
class LDRFilm : public Film {
|
||||||
public:
|
public:
|
||||||
|
@ -176,6 +180,25 @@ public:
|
||||||
m_reinhardKey = props.getFloat("key", 0.18f);
|
m_reinhardKey = props.getFloat("key", 0.18f);
|
||||||
m_reinhardBurn = props.getFloat("burn", 0.0);
|
m_reinhardBurn = props.getFloat("burn", 0.0);
|
||||||
|
|
||||||
|
std::vector<std::string> keys = props.getPropertyNames();
|
||||||
|
for (size_t i=0; i<keys.size(); ++i) {
|
||||||
|
std::string key = boost::to_lower_copy(keys[i]);
|
||||||
|
|
||||||
|
if (boost::starts_with(key, "tag('") && boost::ends_with(key, "')")) {
|
||||||
|
m_tags[keys[i].substr(5, key.length()-7)] = props.getString(keys[i]);
|
||||||
|
} else if (boost::starts_with(key, "text(") && boost::ends_with(key, ")")) {
|
||||||
|
std::vector<std::string> args = tokenize(key.substr(5, key.length()-6), " ,");
|
||||||
|
|
||||||
|
if (args.size() != 2)
|
||||||
|
Log(EError, "Text command '%s' has an invalid number of arguments!", key.c_str());
|
||||||
|
|
||||||
|
Annotation annotation;
|
||||||
|
annotation.offset = Point2i(atoi(args[0].c_str()), atoi(args[1].c_str()));
|
||||||
|
annotation.text = props.getString(keys[i]);
|
||||||
|
m_annotations.push_back(annotation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_storage = new ImageBlock(Bitmap::ESpectrumAlphaWeight, m_cropSize);
|
m_storage = new ImageBlock(Bitmap::ESpectrumAlphaWeight, m_cropSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,6 +336,23 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_annotations.empty()) {
|
||||||
|
ref<Font> font = new Font(Font::EBitstreamVeraMono14);
|
||||||
|
font->convert(bitmap->getPixelFormat(), bitmap->getComponentFormat(), m_gamma);
|
||||||
|
|
||||||
|
for (size_t i=0; i<m_annotations.size(); ++i) {
|
||||||
|
const Point2i &offset = m_annotations[i].offset;
|
||||||
|
const std::string &text = m_annotations[i].text;
|
||||||
|
Vector2i size = font->getSize(text);
|
||||||
|
bitmap->fillRect(offset-Vector2i(4, 4), size + Vector2i(8, 8), Spectrum(0.0f));
|
||||||
|
font->drawText(bitmap, offset, text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::map<std::string, std::string>::const_iterator it = m_tags.begin();
|
||||||
|
it != m_tags.end(); ++it)
|
||||||
|
bitmap->getMetadata()[it->first] = it->second;
|
||||||
|
|
||||||
fs::path filename = m_destFile;
|
fs::path filename = m_destFile;
|
||||||
std::string extension = boost::to_lower_copy(filename.extension().string());
|
std::string extension = boost::to_lower_copy(filename.extension().string());
|
||||||
std::string expectedExtension;
|
std::string expectedExtension;
|
||||||
|
@ -367,6 +407,11 @@ public:
|
||||||
|
|
||||||
MTS_DECLARE_CLASS()
|
MTS_DECLARE_CLASS()
|
||||||
protected:
|
protected:
|
||||||
|
struct Annotation {
|
||||||
|
Point2i offset;
|
||||||
|
std::string text;
|
||||||
|
};
|
||||||
|
|
||||||
Bitmap::EFileFormat m_fileFormat;
|
Bitmap::EFileFormat m_fileFormat;
|
||||||
Bitmap::EPixelFormat m_pixelFormat;
|
Bitmap::EPixelFormat m_pixelFormat;
|
||||||
bool m_hasBanner;
|
bool m_hasBanner;
|
||||||
|
@ -375,6 +420,9 @@ protected:
|
||||||
ref<ImageBlock> m_storage;
|
ref<ImageBlock> m_storage;
|
||||||
ETonemapMethod m_tonemapMethod;
|
ETonemapMethod m_tonemapMethod;
|
||||||
Float m_exposure, m_reinhardKey, m_reinhardBurn;
|
Float m_exposure, m_reinhardKey, m_reinhardBurn;
|
||||||
|
|
||||||
|
std::vector<Annotation> m_annotations;
|
||||||
|
std::map<std::string, std::string> m_tags;
|
||||||
};
|
};
|
||||||
|
|
||||||
MTS_IMPLEMENT_CLASS_S(LDRFilm, false, Film)
|
MTS_IMPLEMENT_CLASS_S(LDRFilm, false, Film)
|
||||||
|
|
|
@ -432,7 +432,7 @@ public:
|
||||||
|
|
||||||
bool develop(const Point2i &sourceOffset, const Vector2i &size,
|
bool develop(const Point2i &sourceOffset, const Vector2i &size,
|
||||||
const Point2i &targetOffset, Bitmap *target) const {
|
const Point2i &targetOffset, Bitmap *target) const {
|
||||||
target->fill(targetOffset, size, Spectrum(0.0f));
|
target->fillRect(targetOffset, size, Spectrum(0.0f));
|
||||||
return false; /* Not supported by the tiled EXR film! */
|
return false; /* Not supported by the tiled EXR film! */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -130,8 +130,7 @@ public:
|
||||||
if (phaseVal != 0) {
|
if (phaseVal != 0) {
|
||||||
/* Calculate prob. of having sampled that direction using
|
/* Calculate prob. of having sampled that direction using
|
||||||
phase function sampling */
|
phase function sampling */
|
||||||
Float phasePdf = (emitter->isOnSurface() && dRec.measure == ESolidAngle
|
Float phasePdf = (emitter->isOnSurface() && dRec.measure == ESolidAngle)
|
||||||
&& interactions == 0)
|
|
||||||
? phase->pdf(pRec) : (Float) 0.0f;
|
? phase->pdf(pRec) : (Float) 0.0f;
|
||||||
|
|
||||||
/* Weight using the power heuristic */
|
/* Weight using the power heuristic */
|
||||||
|
|
|
@ -430,47 +430,59 @@ void Bitmap::flipVertically() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bitmap::accumulate(const Bitmap *bitmap, const Point2i &offset) {
|
|
||||||
|
void Bitmap::accumulate(const Bitmap *bitmap, Point2i sourceOffset,
|
||||||
|
Point2i targetOffset, Vector2i size) {
|
||||||
Assert(getPixelFormat() == bitmap->getPixelFormat() &&
|
Assert(getPixelFormat() == bitmap->getPixelFormat() &&
|
||||||
getComponentFormat() == bitmap->getComponentFormat() &&
|
getComponentFormat() == bitmap->getComponentFormat() &&
|
||||||
getChannelCount() == bitmap->getChannelCount());
|
getChannelCount() == bitmap->getChannelCount());
|
||||||
|
|
||||||
const int
|
Vector2i offsetIncrease(
|
||||||
offsetX = std::max(offset.x, 0),
|
std::max(0, std::max(-sourceOffset.x, -targetOffset.x)),
|
||||||
offsetY = std::max(offset.y, 0),
|
std::max(0, std::max(-sourceOffset.y, -targetOffset.y))
|
||||||
endX = std::min(offset.x + bitmap->getSize().x, m_size.x),
|
);
|
||||||
endY = std::min(offset.y + bitmap->getSize().y, m_size.y);
|
|
||||||
|
|
||||||
if (offsetX >= endX || offsetY >= endY)
|
sourceOffset += offsetIncrease;
|
||||||
|
targetOffset += offsetIncrease;
|
||||||
|
size -= offsetIncrease;
|
||||||
|
|
||||||
|
Vector2i sizeDecrease(
|
||||||
|
std::max(0, std::max(sourceOffset.x + size.x - bitmap->getWidth(), targetOffset.x + size.x - getWidth())),
|
||||||
|
std::max(0, std::max(sourceOffset.y + size.y - bitmap->getHeight(), targetOffset.y + size.y - getHeight())));
|
||||||
|
|
||||||
|
size -= sizeDecrease;
|
||||||
|
|
||||||
|
if (size.x <= 0 || size.y <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const size_t
|
const size_t
|
||||||
columns = (endX - offsetX) * m_channelCount,
|
columns = size.x * m_channelCount,
|
||||||
pixelStride = getBytesPerPixel(),
|
pixelStride = getBytesPerPixel(),
|
||||||
sourceStride = bitmap->getSize().x * pixelStride,
|
sourceStride = bitmap->getWidth() * pixelStride,
|
||||||
targetStride = m_size.x * pixelStride;
|
targetStride = getWidth() * pixelStride;
|
||||||
|
|
||||||
const uint8_t *source = bitmap->getUInt8Data() +
|
const uint8_t *source = bitmap->getUInt8Data() +
|
||||||
(offsetX - offset.x + (offsetY - offset.y) * bitmap->getSize().x) * pixelStride;
|
(sourceOffset.x + sourceOffset.y * (size_t) bitmap->getWidth()) * pixelStride;
|
||||||
|
|
||||||
uint8_t *target = m_data +
|
uint8_t *target = m_data +
|
||||||
(offsetX + offsetY * m_size.x) * pixelStride;
|
(targetOffset.x + targetOffset.y * (size_t) m_size.x) * pixelStride;
|
||||||
|
|
||||||
for (int y = offsetY; y < endY; ++y) {
|
for (int y = 0; y < size.y; ++y) {
|
||||||
switch (m_componentFormat) {
|
switch (m_componentFormat) {
|
||||||
case EUInt8:
|
case EUInt8:
|
||||||
for (size_t i = 0; i < columns; ++i)
|
for (size_t i = 0; i < columns; ++i)
|
||||||
((uint8_t *) target)[i] += ((uint8_t *) source)[i];
|
((uint8_t *) target)[i] = (uint8_t) std::min(0xFF, ((uint8_t *) source)[i] + ((uint8_t *) target)[i]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EUInt16:
|
case EUInt16:
|
||||||
for (size_t i = 0; i < columns; ++i)
|
for (size_t i = 0; i < columns; ++i)
|
||||||
((uint16_t *) target)[i] += ((uint16_t *) source)[i];
|
((uint16_t *) target)[i] = (uint16_t) std::min(0xFFFF, ((uint16_t *) source)[i] + ((uint16_t *) target)[i]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EUInt32:
|
case EUInt32:
|
||||||
for (size_t i = 0; i < columns; ++i)
|
for (size_t i = 0; i < columns; ++i)
|
||||||
((uint32_t *) target)[i] += ((uint32_t *) source)[i];
|
((uint32_t *) target)[i] = std::min((uint32_t) 0xFFFFFFFFUL, ((uint32_t *) source)[i] + ((uint32_t *) target)[i]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EFloat16:
|
case EFloat16:
|
||||||
|
@ -554,8 +566,9 @@ void Bitmap::setPixel(const Point2i &pos, const Spectrum &value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bitmap::drawHLine(int y, int x1, int x2, const Spectrum &value) {
|
void Bitmap::drawHLine(int y, int x1, int x2, const Spectrum &value) {
|
||||||
AssertEx( y >= 0 && y < m_size.y &&
|
if (y < 0 || y >= m_size.y)
|
||||||
x1 >= 0 && x2 < m_size.x, "Bitmap::drawVLine(): out of bounds!");
|
return;
|
||||||
|
x1 = std::max(x1, 0); x2 = std::min(x2, m_size.x-1);
|
||||||
|
|
||||||
const FormatConverter *cvt = FormatConverter::getInstance(
|
const FormatConverter *cvt = FormatConverter::getInstance(
|
||||||
std::make_pair(EFloat, m_componentFormat)
|
std::make_pair(EFloat, m_componentFormat)
|
||||||
|
@ -574,8 +587,9 @@ void Bitmap::drawHLine(int y, int x1, int x2, const Spectrum &value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bitmap::drawVLine(int x, int y1, int y2, const Spectrum &value) {
|
void Bitmap::drawVLine(int x, int y1, int y2, const Spectrum &value) {
|
||||||
AssertEx( x >= 0 && x < m_size.x &&
|
if (x < 0 || x >= m_size.x)
|
||||||
y1 >= 0 && y2 < m_size.y, "Bitmap::drawVLine(): out of bounds!");
|
return;
|
||||||
|
y1 = std::max(y1, 0); y2 = std::min(y2, m_size.y-1);
|
||||||
|
|
||||||
const FormatConverter *cvt = FormatConverter::getInstance(
|
const FormatConverter *cvt = FormatConverter::getInstance(
|
||||||
std::make_pair(EFloat, m_componentFormat)
|
std::make_pair(EFloat, m_componentFormat)
|
||||||
|
@ -601,9 +615,12 @@ void Bitmap::drawRect(const Point2i &offset, const Vector2i &size, const Spectru
|
||||||
drawVLine(offset.x + size.x - 1, offset.y, offset.y + size.y - 1, value);
|
drawVLine(offset.x + size.x - 1, offset.y, offset.y + size.y - 1, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bitmap::fill(const Point2i &offset, const Vector2i &size, const Spectrum &value) {
|
void Bitmap::fillRect(Point2i offset, Vector2i size, const Spectrum &value) {
|
||||||
AssertEx(offset.x >= 0 && offset.x + size.x <= m_size.x &&
|
int sx = std::max(0, -offset.x), sy = std::max(0, -offset.y);
|
||||||
offset.y >= 0 && offset.y + size.y <= m_size.y, "Bitmap::fill(): out of bounds!");
|
size.x -= sx; size.y -= sy; offset.x += sx; offset.y += sy;
|
||||||
|
|
||||||
|
size.x -= std::max(0, offset.x + size.x - m_size.x);
|
||||||
|
size.y -= std::max(0, offset.y + size.y - m_size.y);
|
||||||
|
|
||||||
const FormatConverter *cvt = FormatConverter::getInstance(
|
const FormatConverter *cvt = FormatConverter::getInstance(
|
||||||
std::make_pair(EFloat, m_componentFormat)
|
std::make_pair(EFloat, m_componentFormat)
|
||||||
|
@ -995,6 +1012,79 @@ ref<Bitmap> Bitmap::crop(const Point2i &offset, const Vector2i &size) const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Bitmap::applyMatrix(Float matrix_[3][3]) {
|
||||||
|
int stride = 0;
|
||||||
|
|
||||||
|
if (m_pixelFormat == ERGB || m_pixelFormat == EXYZ)
|
||||||
|
stride = 3;
|
||||||
|
else if (m_pixelFormat == ERGBA || m_pixelFormat == EXYZA)
|
||||||
|
stride = 4;
|
||||||
|
else
|
||||||
|
Log(EError, "Bitmap::applyMatrix(): unsupported pixel format!");
|
||||||
|
|
||||||
|
size_t pixels = (size_t) m_size.x * (size_t) m_size.y;
|
||||||
|
|
||||||
|
switch (m_componentFormat) {
|
||||||
|
case EFloat16: {
|
||||||
|
float matrix[3][3];
|
||||||
|
half *data = getFloat16Data();
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
for (int j=0; j<3; ++j)
|
||||||
|
matrix[i][j] = (float) matrix_[i][j];
|
||||||
|
|
||||||
|
for (size_t i=0; i<pixels; ++i) {
|
||||||
|
float result[3] = { 0.0f, 0.0f, 0.0f };
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
for (int j=0; j<3; ++j)
|
||||||
|
result[i] += matrix[i][j] * (float) data[j];
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
data[i] = (half) result[i];
|
||||||
|
data += stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFloat32: {
|
||||||
|
float matrix[3][3], *data = getFloat32Data();
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
for (int j=0; j<3; ++j)
|
||||||
|
matrix[i][j] = (float) matrix_[i][j];
|
||||||
|
|
||||||
|
for (size_t i=0; i<pixels; ++i) {
|
||||||
|
float result[3] = { 0.0f, 0.0f, 0.0f };
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
for (int j=0; j<3; ++j)
|
||||||
|
result[i] += matrix[i][j] * data[j];
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
data[i] = result[i];
|
||||||
|
data += stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EFloat64: {
|
||||||
|
double matrix[3][3], *data = getFloat64Data();
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
for (int j=0; j<3; ++j)
|
||||||
|
matrix[i][j] = (double) matrix_[i][j];
|
||||||
|
|
||||||
|
for (size_t i=0; i<pixels; ++i) {
|
||||||
|
double result[3] = { 0.0, 0.0, 0.0 };
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
for (int j=0; j<3; ++j)
|
||||||
|
result[i] += matrix[i][j] * data[j];
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
data[i] = result[i];
|
||||||
|
data += stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Log(EError, "Bitmap::applyMatrix(): unsupported component format!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Bitmap resampling utility function
|
/// Bitmap resampling utility function
|
||||||
template <typename Scalar> static void resample(const ReconstructionFilter *rfilter,
|
template <typename Scalar> static void resample(const ReconstructionFilter *rfilter,
|
||||||
ReconstructionFilter::EBoundaryCondition bch,
|
ReconstructionFilter::EBoundaryCondition bch,
|
||||||
|
|
|
@ -78,9 +78,9 @@ void Class::initializeOnce(Class *theClass) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Class::staticInitialization() {
|
void Class::staticInitialization() {
|
||||||
std::for_each(__classes->begin(), __classes->end(),
|
for (ClassMap::iterator it = __classes->begin();
|
||||||
compose1(std::ptr_fun(initializeOnce),
|
it != __classes->end(); ++it)
|
||||||
select2nd<ClassMap::value_type>()));
|
initializeOnce(it->second);
|
||||||
m_isInitialized = true;
|
m_isInitialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -586,18 +586,84 @@ Float fresnelDielectricExt(Float cosThetaI_, Float &cosThetaT_, Float eta) {
|
||||||
return 0.5f * (Rs * Rs + Rp * Rp);
|
return 0.5f * (Rs * Rs + Rp * Rp);
|
||||||
}
|
}
|
||||||
|
|
||||||
Spectrum fresnelConductor(Float cosThetaI, const Spectrum &eta, const Spectrum &k) {
|
Float fresnelConductorApprox(Float cosThetaI, Float eta, Float k) {
|
||||||
Spectrum tmp = (eta*eta + k*k) * (cosThetaI * cosThetaI);
|
Float cosThetaI2 = cosThetaI*cosThetaI;
|
||||||
|
|
||||||
Spectrum rParl2 = (tmp - (eta * (2.0f * cosThetaI)) + Spectrum(1.0f))
|
Float tmp = (eta*eta + k*k) * cosThetaI2;
|
||||||
/ (tmp + (eta * (2.0f * cosThetaI)) + Spectrum(1.0f));
|
|
||||||
|
Float Rp2 = (tmp - (eta * (2 * cosThetaI)) + 1)
|
||||||
|
/ (tmp + (eta * (2 * cosThetaI)) + 1);
|
||||||
|
|
||||||
|
Float tmpF = eta*eta + k*k;
|
||||||
|
|
||||||
|
Float Rs2 = (tmpF - (eta * (2 * cosThetaI)) + cosThetaI2) /
|
||||||
|
(tmpF + (eta * (2 * cosThetaI)) + cosThetaI2);
|
||||||
|
|
||||||
|
return 0.5f * (Rp2 + Rs2);
|
||||||
|
}
|
||||||
|
|
||||||
|
Spectrum fresnelConductorApprox(Float cosThetaI, const Spectrum &eta, const Spectrum &k) {
|
||||||
|
Float cosThetaI2 = cosThetaI*cosThetaI;
|
||||||
|
|
||||||
|
Spectrum tmp = (eta*eta + k*k) * cosThetaI2;
|
||||||
|
|
||||||
|
Spectrum Rp2 = (tmp - (eta * (2 * cosThetaI)) + Spectrum(1.0f))
|
||||||
|
/ (tmp + (eta * (2 * cosThetaI)) + Spectrum(1.0f));
|
||||||
|
|
||||||
Spectrum tmpF = eta*eta + k*k;
|
Spectrum tmpF = eta*eta + k*k;
|
||||||
|
|
||||||
Spectrum rPerp2 = (tmpF - (eta * (2.0f * cosThetaI)) + Spectrum(cosThetaI*cosThetaI)) /
|
Spectrum Rs2 = (tmpF - (eta * (2 * cosThetaI)) + Spectrum(cosThetaI2)) /
|
||||||
(tmpF + (eta * (2.0f * cosThetaI)) + Spectrum(cosThetaI*cosThetaI));
|
(tmpF + (eta * (2 * cosThetaI)) + Spectrum(cosThetaI2));
|
||||||
|
|
||||||
return (rParl2 + rPerp2) / 2.0f;
|
return 0.5f * (Rp2 + Rs2);
|
||||||
|
}
|
||||||
|
|
||||||
|
Float fresnelConductorExact(Float cosThetaI, Float eta, Float k) {
|
||||||
|
/* Modified from "Optics" by K.D. Moeller, University Science Books, 1988 */
|
||||||
|
|
||||||
|
Float cosThetaI2 = cosThetaI*cosThetaI,
|
||||||
|
sinThetaI2 = 1-cosThetaI2,
|
||||||
|
sinThetaI4 = sinThetaI2*sinThetaI2;
|
||||||
|
|
||||||
|
Float temp1 = eta*eta - k*k - sinThetaI2,
|
||||||
|
a2pb2 = math::safe_sqrt(temp1*temp1 + 4*k*k*eta*eta),
|
||||||
|
a = math::safe_sqrt(0.5f * (a2pb2 + temp1));
|
||||||
|
|
||||||
|
Float term1 = a2pb2 + cosThetaI2,
|
||||||
|
term2 = 2*a*cosThetaI;
|
||||||
|
|
||||||
|
Float Rs2 = (term1 - term2) / (term1 + term2);
|
||||||
|
|
||||||
|
Float term3 = a2pb2*cosThetaI2 + sinThetaI4,
|
||||||
|
term4 = term2*sinThetaI2;
|
||||||
|
|
||||||
|
Float Rp2 = Rs2 * (term3 - term4) / (term3 + term4);
|
||||||
|
|
||||||
|
return 0.5f * (Rp2 + Rs2);
|
||||||
|
}
|
||||||
|
|
||||||
|
Spectrum fresnelConductorExact(Float cosThetaI, const Spectrum &eta, const Spectrum &k) {
|
||||||
|
/* Modified from "Optics" by K.D. Moeller, University Science Books, 1988 */
|
||||||
|
|
||||||
|
Float cosThetaI2 = cosThetaI*cosThetaI,
|
||||||
|
sinThetaI2 = 1-cosThetaI2,
|
||||||
|
sinThetaI4 = sinThetaI2*sinThetaI2;
|
||||||
|
|
||||||
|
Spectrum temp1 = eta*eta - k*k - Spectrum(sinThetaI2),
|
||||||
|
a2pb2 = (temp1*temp1 + k*k*eta*eta*4).safe_sqrt(),
|
||||||
|
a = ((a2pb2 + temp1) * 0.5f).safe_sqrt();
|
||||||
|
|
||||||
|
Spectrum term1 = a2pb2 + Spectrum(cosThetaI2),
|
||||||
|
term2 = a*(2*cosThetaI);
|
||||||
|
|
||||||
|
Spectrum Rs2 = (term1 - term2) / (term1 + term2);
|
||||||
|
|
||||||
|
Spectrum term3 = a2pb2*cosThetaI2 + Spectrum(sinThetaI4),
|
||||||
|
term4 = term2*sinThetaI2;
|
||||||
|
|
||||||
|
Spectrum Rp2 = Rs2 * (term3 - term4) / (term3 + term4);
|
||||||
|
|
||||||
|
return 0.5f * (Rp2 + Rs2);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector reflect(const Vector &wi, const Normal &n) {
|
Vector reflect(const Vector &wi, const Normal &n) {
|
||||||
|
|
|
@ -74,6 +74,70 @@ Font::Font(EFont font) {
|
||||||
dscStream->read(m_kerningMatrix, 256*256);
|
dscStream->read(m_kerningMatrix, 256*256);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Font::convert(Bitmap::EPixelFormat pixelFormat, Bitmap::EComponentFormat componentFormat, Float gamma) {
|
||||||
|
m_bitmap = m_bitmap->convert(pixelFormat, componentFormat, gamma);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Font::drawText(Bitmap *dest, Point2i pos, const std::string &text) const {
|
||||||
|
int initial = pos.x;
|
||||||
|
|
||||||
|
for (size_t i=0; i<text.length(); i++) {
|
||||||
|
char character = text[i];
|
||||||
|
if (character == '\r')
|
||||||
|
continue;
|
||||||
|
if (character == '\n') {
|
||||||
|
pos.x = initial;
|
||||||
|
pos.y += (int) (getMaxVerticalBearing()*4.0/3.0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Font::Glyph &glyph = getGlyph(character);
|
||||||
|
|
||||||
|
Point2i targetOffset = pos + Vector2i(
|
||||||
|
glyph.horizontalBearing,
|
||||||
|
getMaxVerticalBearing() - glyph.verticalBearing - 1
|
||||||
|
);
|
||||||
|
|
||||||
|
Point2i sourceOffset(
|
||||||
|
glyph.tx.x * m_bitmap->getWidth(),
|
||||||
|
glyph.tx.y * m_bitmap->getHeight());
|
||||||
|
|
||||||
|
dest->accumulate(m_bitmap.get(), sourceOffset, targetOffset, glyph.size);
|
||||||
|
|
||||||
|
pos.x += glyph.horizontalAdvance;
|
||||||
|
|
||||||
|
if (i+1 < text.length())
|
||||||
|
pos.x += getKerning(character, text[i+1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2i Font::getSize(const std::string &text) const {
|
||||||
|
Vector2i size(0, getMaxVerticalBearing());
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
for (size_t i=0; i<text.length(); i++) {
|
||||||
|
char character = text[i];
|
||||||
|
if (character == '\r')
|
||||||
|
continue;
|
||||||
|
if (character == '\n') {
|
||||||
|
size.y += getMaxVerticalBearing()*(4.0 / 3.0);
|
||||||
|
size.x = std::max(size.x, pos);
|
||||||
|
pos = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Font::Glyph &glyph = getGlyph(character);
|
||||||
|
|
||||||
|
pos += glyph.horizontalAdvance;
|
||||||
|
|
||||||
|
if (i+1 < text.length())
|
||||||
|
pos += getKerning(character, text[i+1]);
|
||||||
|
}
|
||||||
|
size.x = std::max(size.x, pos);
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
void Font::init(Renderer *renderer) {
|
void Font::init(Renderer *renderer) {
|
||||||
m_texture = renderer->createGPUTexture(m_name, m_bitmap);
|
m_texture = renderer->createGPUTexture(m_name, m_bitmap);
|
||||||
m_texture->setFilterType(GPUTexture::ENearest);
|
m_texture->setFilterType(GPUTexture::ENearest);
|
||||||
|
|
|
@ -79,10 +79,10 @@ void initializeFramework() {
|
||||||
if (GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
|
if (GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
|
||||||
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCSTR) &initializeFramework, &hm)) {
|
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCSTR) &initializeFramework, &hm)) {
|
||||||
std::vector<WCHAR> lpFilename(MAX_PATH);
|
std::vector<WCHAR> lpFilename(MAX_PATH);
|
||||||
|
|
||||||
// Try to get the path with the default MAX_PATH length (260 chars)
|
// Try to get the path with the default MAX_PATH length (260 chars)
|
||||||
DWORD nSize = GetModuleFileNameW(hm, &lpFilename[0], MAX_PATH);
|
DWORD nSize = GetModuleFileNameW(hm, &lpFilename[0], MAX_PATH);
|
||||||
|
|
||||||
// Adjust the buffer size in case if was too short
|
// Adjust the buffer size in case if was too short
|
||||||
while (nSize == lpFilename.size()) {
|
while (nSize == lpFilename.size()) {
|
||||||
lpFilename.resize(nSize * 2);
|
lpFilename.resize(nSize * 2);
|
||||||
|
@ -175,7 +175,7 @@ public:
|
||||||
bp::extract<Transform> extractTransform(value);
|
bp::extract<Transform> extractTransform(value);
|
||||||
bp::extract<Spectrum> extractSpectrum(value);
|
bp::extract<Spectrum> extractSpectrum(value);
|
||||||
|
|
||||||
if (extractString.check()) {
|
if (extractString.check()){
|
||||||
props.setString(name, extractString());
|
props.setString(name, extractString());
|
||||||
} else if (extractBoolean.check() && PyObject_IsInstance(value.ptr(), (PyObject *) &PyBool_Type)) {
|
} else if (extractBoolean.check() && PyObject_IsInstance(value.ptr(), (PyObject *) &PyBool_Type)) {
|
||||||
props.setBoolean(name, extractBoolean());
|
props.setBoolean(name, extractBoolean());
|
||||||
|
@ -205,6 +205,12 @@ struct path_to_python_str {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct TSpectrum_to_Spectrum {
|
||||||
|
static PyObject* convert(const TSpectrum<Float, 3> &spectrum) {
|
||||||
|
return bp::incref(bp::object(Spectrum(spectrum)).ptr());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static void Matrix4x4_setItem(Matrix4x4 *matrix, bp::tuple tuple, Float value) {
|
static void Matrix4x4_setItem(Matrix4x4 *matrix, bp::tuple tuple, Float value) {
|
||||||
if (bp::len(tuple) != 2)
|
if (bp::len(tuple) != 2)
|
||||||
SLog(EError, "Invalid matrix indexing operation, required a tuple of length 2");
|
SLog(EError, "Invalid matrix indexing operation, required a tuple of length 2");
|
||||||
|
@ -472,6 +478,43 @@ Vector refract3(const Vector &wi, const Normal &n, Float eta) {
|
||||||
return refract(wi, n, eta);
|
return refract(wi, n, eta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bitmap_applyMatrix(Bitmap *bitmap, bp::list list) {
|
||||||
|
int length = bp::len(list);
|
||||||
|
if (length != 9)
|
||||||
|
SLog(EError, "Require a color matrix specified as a list with 9 entries!");
|
||||||
|
|
||||||
|
Float matrix[3][3];
|
||||||
|
|
||||||
|
int idx = 0;
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
for (int j=0; j<3; ++j)
|
||||||
|
matrix[i][j] = bp::extract<Float>(list[idx++]);
|
||||||
|
|
||||||
|
bitmap->applyMatrix(matrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bitmap_write(Bitmap *bitmap, Bitmap::EFileFormat fmt, Stream *stream) {
|
||||||
|
bitmap->write(fmt, stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
ref<Bitmap> bitmap_convert_1(Bitmap *bitmap, Bitmap::EPixelFormat pixelFormat, Bitmap::EComponentFormat componentFormat,
|
||||||
|
Float gamma, Float multiplier, Spectrum::EConversionIntent intent) {
|
||||||
|
return bitmap->convert(pixelFormat, componentFormat, gamma, multiplier, intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
ref<Bitmap> bitmap_convert_2(Bitmap *bitmap, Bitmap::EPixelFormat pixelFormat, Bitmap::EComponentFormat componentFormat,
|
||||||
|
Float gamma, Float multiplier) {
|
||||||
|
return bitmap->convert(pixelFormat, componentFormat, gamma, multiplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
ref<Bitmap> bitmap_convert_3(Bitmap *bitmap, Bitmap::EPixelFormat pixelFormat, Bitmap::EComponentFormat componentFormat,
|
||||||
|
Float gamma) {
|
||||||
|
return bitmap->convert(pixelFormat, componentFormat, gamma);
|
||||||
|
}
|
||||||
|
|
||||||
|
ref<Bitmap> bitmap_convert_4(Bitmap *bitmap, Bitmap::EPixelFormat pixelFormat, Bitmap::EComponentFormat componentFormat) {
|
||||||
|
return bitmap->convert(pixelFormat, componentFormat);
|
||||||
|
}
|
||||||
|
|
||||||
Transform transform_glOrthographic1(Float clipNear, Float clipFar) {
|
Transform transform_glOrthographic1(Float clipNear, Float clipFar) {
|
||||||
return Transform::glOrthographic(clipNear, clipFar);
|
return Transform::glOrthographic(clipNear, clipFar);
|
||||||
|
@ -489,6 +532,7 @@ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(fromXYZ_overloads, fromXYZ, 3, 4)
|
||||||
|
|
||||||
void export_core() {
|
void export_core() {
|
||||||
bp::to_python_converter<fs::path, path_to_python_str>();
|
bp::to_python_converter<fs::path, path_to_python_str>();
|
||||||
|
bp::to_python_converter<TSpectrum<Float, 3>, TSpectrum_to_Spectrum>();
|
||||||
bp::implicitly_convertible<std::string, fs::path>();
|
bp::implicitly_convertible<std::string, fs::path>();
|
||||||
|
|
||||||
bp::object coreModule(
|
bp::object coreModule(
|
||||||
|
@ -708,17 +752,23 @@ void export_core() {
|
||||||
.def("clear", &InterpolatedSpectrum::clear)
|
.def("clear", &InterpolatedSpectrum::clear)
|
||||||
.def("zeroExtend", &InterpolatedSpectrum::zeroExtend);
|
.def("zeroExtend", &InterpolatedSpectrum::zeroExtend);
|
||||||
|
|
||||||
|
void (Bitmap::*accumulate_1)(const Bitmap *bitmap, Point2i sourceOffset, Point2i targetOffset, Vector2i size) = &Bitmap::accumulate;
|
||||||
|
void (Bitmap::*accumulate_2)(const Bitmap *bitmap, Point2i targetOffset) = &Bitmap::accumulate;
|
||||||
|
|
||||||
BP_CLASS(Bitmap, Object, (bp::init<Bitmap::EPixelFormat, Bitmap::EComponentFormat, const Vector2i &>()))
|
BP_CLASS(Bitmap, Object, (bp::init<Bitmap::EPixelFormat, Bitmap::EComponentFormat, const Vector2i &>()))
|
||||||
.def(bp::init<Bitmap::EPixelFormat, Bitmap::EComponentFormat, const Vector2i &, int>())
|
.def(bp::init<Bitmap::EPixelFormat, Bitmap::EComponentFormat, const Vector2i &, int>())
|
||||||
.def(bp::init<Bitmap::EFileFormat, Stream *>())
|
.def(bp::init<Bitmap::EFileFormat, Stream *>())
|
||||||
.def("clone", &Bitmap::clone, BP_RETURN_VALUE)
|
.def("clone", &Bitmap::clone, BP_RETURN_VALUE)
|
||||||
|
.def("clear", &Bitmap::clear)
|
||||||
.def("separateChannel", &Bitmap::separateChannel, BP_RETURN_VALUE)
|
.def("separateChannel", &Bitmap::separateChannel, BP_RETURN_VALUE)
|
||||||
.def("expand", &Bitmap::expand, BP_RETURN_VALUE)
|
.def("expand", &Bitmap::expand, BP_RETURN_VALUE)
|
||||||
.def("flipVertically", &Bitmap::flipVertically)
|
.def("flipVertically", &Bitmap::flipVertically)
|
||||||
.def("crop", &Bitmap::crop)
|
.def("crop", &Bitmap::crop)
|
||||||
.def("accumulate", &Bitmap::accumulate)
|
.def("applyMatrix", &bitmap_applyMatrix)
|
||||||
.def("clear", &Bitmap::clear)
|
.def("colorBalance", &Bitmap::colorBalance)
|
||||||
.def("write", &Bitmap::write)
|
.def("accumulate", accumulate_1)
|
||||||
|
.def("accumulate", accumulate_2)
|
||||||
|
.def("write", &bitmap_write)
|
||||||
.def("setString", &Bitmap::setString)
|
.def("setString", &Bitmap::setString)
|
||||||
.def("getString", &Bitmap::getString, BP_RETURN_VALUE)
|
.def("getString", &Bitmap::getString, BP_RETURN_VALUE)
|
||||||
.def("setGamma", &Bitmap::setGamma)
|
.def("setGamma", &Bitmap::setGamma)
|
||||||
|
@ -732,9 +782,18 @@ void export_core() {
|
||||||
.def("getBitsPerComponent", &Bitmap::getBitsPerComponent)
|
.def("getBitsPerComponent", &Bitmap::getBitsPerComponent)
|
||||||
.def("getBytesPerComponent", &Bitmap::getBytesPerComponent)
|
.def("getBytesPerComponent", &Bitmap::getBytesPerComponent)
|
||||||
.def("getBytesPerPixel", &Bitmap::getBytesPerPixel)
|
.def("getBytesPerPixel", &Bitmap::getBytesPerPixel)
|
||||||
|
.def("getBufferSize", &Bitmap::getBufferSize)
|
||||||
.def("getPixel", &Bitmap::getPixel, BP_RETURN_VALUE)
|
.def("getPixel", &Bitmap::getPixel, BP_RETURN_VALUE)
|
||||||
.def("setPixel", &Bitmap::setPixel)
|
.def("setPixel", &Bitmap::setPixel)
|
||||||
.def("getSize", &Bitmap::getSize, BP_RETURN_VALUE);
|
.def("drawHLine", &Bitmap::drawHLine)
|
||||||
|
.def("drawVLine", &Bitmap::drawVLine)
|
||||||
|
.def("drawRect", &Bitmap::drawRect)
|
||||||
|
.def("fillRect", &Bitmap::fillRect)
|
||||||
|
.def("getSize", &Bitmap::getSize, BP_RETURN_VALUE)
|
||||||
|
.def("convert", &bitmap_convert_1, BP_RETURN_VALUE)
|
||||||
|
.def("convert", &bitmap_convert_2, BP_RETURN_VALUE)
|
||||||
|
.def("convert", &bitmap_convert_3, BP_RETURN_VALUE)
|
||||||
|
.def("convert", &bitmap_convert_4, BP_RETURN_VALUE);
|
||||||
|
|
||||||
BP_SETSCOPE(Bitmap_class);
|
BP_SETSCOPE(Bitmap_class);
|
||||||
bp::enum_<Bitmap::EPixelFormat>("EPixelFormat")
|
bp::enum_<Bitmap::EPixelFormat>("EPixelFormat")
|
||||||
|
@ -745,7 +804,8 @@ void export_core() {
|
||||||
.value("ESpectrum", Bitmap::ESpectrum)
|
.value("ESpectrum", Bitmap::ESpectrum)
|
||||||
.value("ESpectrumAlpha", Bitmap::ESpectrumAlpha)
|
.value("ESpectrumAlpha", Bitmap::ESpectrumAlpha)
|
||||||
.value("ESpectrumAlphaWeight", Bitmap::ESpectrumAlphaWeight)
|
.value("ESpectrumAlphaWeight", Bitmap::ESpectrumAlphaWeight)
|
||||||
.value("EMultiChannel", Bitmap::EMultiChannel);
|
.value("EMultiChannel", Bitmap::EMultiChannel)
|
||||||
|
.export_values();
|
||||||
|
|
||||||
bp::enum_<Bitmap::EComponentFormat>("EComponentFormat")
|
bp::enum_<Bitmap::EComponentFormat>("EComponentFormat")
|
||||||
.value("EBitmask", Bitmap::EBitmask)
|
.value("EBitmask", Bitmap::EBitmask)
|
||||||
|
@ -763,10 +823,13 @@ void export_core() {
|
||||||
.value("EPNG", Bitmap::EPNG)
|
.value("EPNG", Bitmap::EPNG)
|
||||||
.value("EOpenEXR", Bitmap::EOpenEXR)
|
.value("EOpenEXR", Bitmap::EOpenEXR)
|
||||||
.value("ETGA", Bitmap::ETGA)
|
.value("ETGA", Bitmap::ETGA)
|
||||||
|
.value("EPFM", Bitmap::EPFM)
|
||||||
|
.value("ERGBE", Bitmap::ERGBE)
|
||||||
.value("EBMP", Bitmap::EBMP)
|
.value("EBMP", Bitmap::EBMP)
|
||||||
.value("EJPEG", Bitmap::EJPEG)
|
.value("EJPEG", Bitmap::EJPEG)
|
||||||
.value("EAuto", Bitmap::EAuto)
|
.value("EAuto", Bitmap::EAuto)
|
||||||
.export_values();
|
.export_values();
|
||||||
|
|
||||||
BP_SETSCOPE(coreModule);
|
BP_SETSCOPE(coreModule);
|
||||||
|
|
||||||
BP_CLASS(FileResolver, Object, bp::init<>())
|
BP_CLASS(FileResolver, Object, bp::init<>())
|
||||||
|
@ -1261,11 +1324,19 @@ void export_core() {
|
||||||
.staticmethod("glOrthographic")
|
.staticmethod("glOrthographic")
|
||||||
.staticmethod("fromFrame");
|
.staticmethod("fromFrame");
|
||||||
|
|
||||||
|
Float (*fresnelConductorApprox1)(Float, Float, Float) = &fresnelConductorApprox;
|
||||||
|
Float (*fresnelConductorExact1)(Float, Float, Float) = &fresnelConductorExact;
|
||||||
|
Spectrum (*fresnelConductorApprox2)(Float, const Spectrum &, const Spectrum &) = &fresnelConductorApprox;
|
||||||
|
Spectrum (*fresnelConductorExact2)(Float, const Spectrum &, const Spectrum &) = &fresnelConductorExact;
|
||||||
|
|
||||||
/* Functions from utility.h */
|
/* Functions from utility.h */
|
||||||
bp::def("fresnelDielectric", &fresnelDielectric);
|
bp::def("fresnelDielectric", &fresnelDielectric);
|
||||||
bp::def("fresnelDielectricExt", &fresnelDielectricExt1);
|
bp::def("fresnelDielectricExt", &fresnelDielectricExt1);
|
||||||
bp::def("fresnelDielectricExt", &fresnelDielectricExt2);
|
bp::def("fresnelDielectricExt", &fresnelDielectricExt2);
|
||||||
bp::def("fresnelConductor", &fresnelConductor, BP_RETURN_VALUE);
|
bp::def("fresnelConductorApprox", fresnelConductorApprox1, BP_RETURN_VALUE);
|
||||||
|
bp::def("fresnelConductorApprox", fresnelConductorApprox2, BP_RETURN_VALUE);
|
||||||
|
bp::def("fresnelConductorExact", fresnelConductorExact1, BP_RETURN_VALUE);
|
||||||
|
bp::def("fresnelConductorExact", fresnelConductorExact2, BP_RETURN_VALUE);
|
||||||
bp::def("fresnelDiffuseReflectance", &fresnelDiffuseReflectance);
|
bp::def("fresnelDiffuseReflectance", &fresnelDiffuseReflectance);
|
||||||
bp::def("reflect", &reflect);
|
bp::def("reflect", &reflect);
|
||||||
bp::def("refract", &refract1);
|
bp::def("refract", &refract1);
|
||||||
|
|
|
@ -47,6 +47,7 @@ Spectrum Texture::getMinimum() const { NotImplementedError("getMinimum"); }
|
||||||
Spectrum Texture::getMaximum() const { NotImplementedError("getMaximum"); }
|
Spectrum Texture::getMaximum() const { NotImplementedError("getMaximum"); }
|
||||||
bool Texture::isConstant() const { NotImplementedError("isConstant"); }
|
bool Texture::isConstant() const { NotImplementedError("isConstant"); }
|
||||||
bool Texture::usesRayDifferentials() const { NotImplementedError("usesRayDifferentials"); }
|
bool Texture::usesRayDifferentials() const { NotImplementedError("usesRayDifferentials"); }
|
||||||
|
ref<Bitmap> Texture::getBitmap() const { return NULL; }
|
||||||
|
|
||||||
ref<Texture> Texture::expand() {
|
ref<Texture> Texture::expand() {
|
||||||
return this;
|
return this;
|
||||||
|
|
|
@ -33,9 +33,8 @@ if hasQt:
|
||||||
del qtEnv['CXXFLAGS'][index-1]
|
del qtEnv['CXXFLAGS'][index-1]
|
||||||
index = qtEnv['LINKFLAGS'].index('/SUBSYSTEM:CONSOLE')
|
index = qtEnv['LINKFLAGS'].index('/SUBSYSTEM:CONSOLE')
|
||||||
del qtEnv['LINKFLAGS'][index]
|
del qtEnv['LINKFLAGS'][index]
|
||||||
qtEnv.Append(CXXFLAGS=['/D', '_WINDOWS'])
|
qtEnv.Append(CXXFLAGS=['/D', '_WINDOWS', '/D', 'MTS_CUSTOM_QTMAIN', '/D', 'MTSGUI_STATIC_QFILEDIALOG=1'])
|
||||||
qtEnv.Append(LINKFLAGS=['/SUBSYSTEM:WINDOWS'])
|
qtEnv.Append(LINKFLAGS=['/SUBSYSTEM:WINDOWS'])
|
||||||
qtEnv.Append(LIBS=['qtmain'])
|
|
||||||
if hasBreakpad:
|
if hasBreakpad:
|
||||||
qtEnv.Append(CPPPATH=['#dependencies/include/breakpad'])
|
qtEnv.Append(CPPPATH=['#dependencies/include/breakpad'])
|
||||||
qtEnv.Append(LIBS=['breakpad_common', 'breakpad_exception_handler', 'breakpad_crash_generation_client',
|
qtEnv.Append(LIBS=['breakpad_common', 'breakpad_exception_handler', 'breakpad_crash_generation_client',
|
||||||
|
@ -72,6 +71,10 @@ if hasQt:
|
||||||
qtSources += qtEnv_osx.StaticObject('breakpad.mm')
|
qtSources += qtEnv_osx.StaticObject('breakpad.mm')
|
||||||
else:
|
else:
|
||||||
qtSources = [x for x in qtSources if (not isinstance(x, str) or 'cocoa' not in x)]
|
qtSources = [x for x in qtSources if (not isinstance(x, str) or 'cocoa' not in x)]
|
||||||
|
|
||||||
|
if sys.platform == 'win32':
|
||||||
|
qtSources += qtEnv.StaticObject('qtmain_win.cpp')
|
||||||
|
|
||||||
mtsgui = qtEnv.Program('mtsgui', qtSources)
|
mtsgui = qtEnv.Program('mtsgui', qtSources)
|
||||||
if sys.platform == 'darwin':
|
if sys.platform == 'darwin':
|
||||||
qtEnv.AddPostAction(mtsgui, 'install_name_tool -change QtGui.framework/Versions/4/QtGui @rpath/QtGui $TARGET')
|
qtEnv.AddPostAction(mtsgui, 'install_name_tool -change QtGui.framework/Versions/4/QtGui @rpath/QtGui $TARGET')
|
||||||
|
|
|
@ -558,6 +558,8 @@ void MainWindow::on_actionOpen_triggered() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::onOpenDialogClose(int reason) { /* unused */ }
|
||||||
|
|
||||||
#else // MTSGUI_STATIC_QFILEDIALOG
|
#else // MTSGUI_STATIC_QFILEDIALOG
|
||||||
|
|
||||||
void MainWindow::on_actionOpen_triggered() {
|
void MainWindow::on_actionOpen_triggered() {
|
||||||
|
@ -1447,6 +1449,8 @@ void MainWindow::on_actionExportImage_triggered() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::onExportDialogClose(int reason) { /* unused */ }
|
||||||
|
|
||||||
#else // MTSGUI_STATIC_QFILEDIALOG
|
#else // MTSGUI_STATIC_QFILEDIALOG
|
||||||
|
|
||||||
void MainWindow::on_actionExportImage_triggered() {
|
void MainWindow::on_actionExportImage_triggered() {
|
||||||
|
@ -1563,6 +1567,8 @@ void MainWindow::on_actionSaveAs_triggered() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::onSaveAsDialogClose(int reason) { /* unused */ }
|
||||||
|
|
||||||
#else // MTSGUI_STATIC_QFILEDIALOG
|
#else // MTSGUI_STATIC_QFILEDIALOG
|
||||||
|
|
||||||
void MainWindow::on_actionSaveAs_triggered() {
|
void MainWindow::on_actionSaveAs_triggered() {
|
||||||
|
|
|
@ -192,11 +192,9 @@ private slots:
|
||||||
void updateUI();
|
void updateUI();
|
||||||
void updateStatus();
|
void updateStatus();
|
||||||
void onPreviewSettingsClose();
|
void onPreviewSettingsClose();
|
||||||
#if !MTSGUI_STATIC_QFILEDIALOG
|
|
||||||
void onOpenDialogClose(int reason);
|
void onOpenDialogClose(int reason);
|
||||||
void onExportDialogClose(int reason);
|
void onExportDialogClose(int reason);
|
||||||
void onSaveAsDialogClose(int reason);
|
void onSaveAsDialogClose(int reason);
|
||||||
#endif
|
|
||||||
void onRenderSettingsClose(int reason);
|
void onRenderSettingsClose(int reason);
|
||||||
void onImportDialogClose(int reason);
|
void onImportDialogClose(int reason);
|
||||||
void onSceneInformationClose(int reason);
|
void onSceneInformationClose(int reason);
|
||||||
|
|
|
@ -44,12 +44,12 @@
|
||||||
# error This source file can only be used in Windows builds
|
# error This source file can only be used in Windows builds
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <QVector>
|
#include <QtCore/QVector>
|
||||||
#include <QByteArray>
|
#include <QtCore/QByteArray>
|
||||||
#include <QString>
|
#include <QtCore/QString>
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#include <Windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This file contains the code in the qtmain library for Windows.
|
This file contains the code in the qtmain library for Windows.
|
||||||
|
|
|
@ -208,9 +208,9 @@ static int irrOctreeIndex = 0;
|
||||||
* rendered using diffusion theory and radiative transport, respectively.
|
* rendered using diffusion theory and radiative transport, respectively.
|
||||||
* The former produces an incorrect result, since the assumption of
|
* The former produces an incorrect result, since the assumption of
|
||||||
* many scattering events breaks down.
|
* many scattering events breaks down.
|
||||||
* \textbf{(c)}: When the number of irradiance samples is too low, the
|
* \textbf{(c)}: When the number of irradiance samples is too low when rendering
|
||||||
* resulting noise becomes visible as ``blotchy'' artifacts in the
|
* with the dipole model, the resulting noise becomes visible as ``blotchy'' artifacts
|
||||||
* rendering.}
|
* in the rendering.}
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* \subsubsection*{Typical material setup}
|
* \subsubsection*{Typical material setup}
|
||||||
|
|
|
@ -400,6 +400,10 @@ public:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ref<Bitmap> getBitmap() const {
|
||||||
|
return m_mipmap1.get() ? m_mipmap1->toBitmap() : m_mipmap3->toBitmap();
|
||||||
|
}
|
||||||
|
|
||||||
Spectrum eval(const Point2 &uv, const Vector2 &d0, const Vector2 &d1) const {
|
Spectrum eval(const Point2 &uv, const Vector2 &d0, const Vector2 &d1) const {
|
||||||
stats::filteredLookups.incrementBase();
|
stats::filteredLookups.incrementBase();
|
||||||
++stats::filteredLookups;
|
++stats::filteredLookups;
|
||||||
|
|
|
@ -93,7 +93,7 @@ MTS_NAMESPACE_BEGIN
|
||||||
*
|
*
|
||||||
* When using this data source to represent floating point density volumes,
|
* When using this data source to represent floating point density volumes,
|
||||||
* please ensure that the values are all normalized to lie in the
|
* please ensure that the values are all normalized to lie in the
|
||||||
* range $[0, 1]$---otherwise, the Woocock-Tracking integration method in
|
* range $[0, 1]$---otherwise, the Woodcock-Tracking integration method in
|
||||||
* \pluginref{heterogeneous} will produce incorrect results.
|
* \pluginref{heterogeneous} will produce incorrect results.
|
||||||
*/
|
*/
|
||||||
class GridDataSource : public VolumeDataSource {
|
class GridDataSource : public VolumeDataSource {
|
||||||
|
|
Loading…
Reference in New Issue