merge with default branch

metadata
Wenzel Jakob 2010-10-07 18:57:44 +02:00
commit 05266a5033
20 changed files with 217 additions and 101 deletions

View File

@ -11,8 +11,9 @@
.*moc_.*\.cc$ .*moc_.*\.cc$
.*qrc_.*\.cc$ .*qrc_.*\.cc$
# SCons-related # Build-related
^\.sconf_temp/.*$ ^\.sconf_temp/.*$
^debian/.*$
^.sconsign.dblite$ ^.sconsign.dblite$
^config.py$ ^config.py$
^config.log$ ^config.log$

View File

@ -52,11 +52,11 @@ using another distribution.
First, run First, run
\begin{shell} \begin{shell}
$\text{\$}$ apt-get install build-essential scons qt4-dev-tools scons libpng12-dev libjpeg62-dev libilmbase-dev libopenexr-dev libxerces-c-dev libboost-dev libglewmx1.5-dev libxxf86vm-dev libboost-system-dev libboost-filesystem-dev $\text{\$}$ sudo apt-get install build-essential scons qt4-dev-tools scons libpng12-dev libjpeg62-dev libilmbase-dev libopenexr-dev libxerces-c-dev libboost-dev libglewmx1.5-dev libxxf86vm-dev libboost-system-dev libboost-filesystem-dev
\end{shell} \end{shell}
To get COLLADA support, you will also need to install the \texttt{collada-dom} packages or build them from scratch. Here, we install the \code{x86\_64} binaries and development headers included with Mitsuba: To get COLLADA support, you will also need to install the \texttt{collada-dom} packages or build them from scratch. Here, we install the \code{x86\_64} binaries and development headers included with Mitsuba:
\begin{shell} \begin{shell}
$\text{\$}$ dpkg --install tools/linux/collada-dom2.2_2.2-1_amd64.deb tools/linux/collada-dom-dev_2.2-1_amd64.deb $\text{\$}$ sudo dpkg --install tools/linux/collada-dom2.2_2.2-1_amd64.deb tools/linux/collada-dom-dev_2.2-1_amd64.deb
\end{shell} \end{shell}
Afterwards, simply run Afterwards, simply run
\begin{shell} \begin{shell}
@ -82,7 +82,38 @@ First, run
\begin{shell} \begin{shell}
$\text{\$}$ yum install mercurial gcc-c++ scons boost-devel qt4-devel OpenEXR-devel xerces-c-devel $\text{\$}$ yum install mercurial gcc-c++ scons boost-devel qt4-devel OpenEXR-devel xerces-c-devel
\end{shell} \end{shell}
You will also need the \texttt{glew-mx} and \texttt{collada-dom} packages, which are not included in the Fedora package repository. You can grab source and \texttt{i386} binary \texttt{RPM} files here: \texttt{http://www.mitsuba-renderer.org/releases}. You will also need the \texttt{glew-mx} and \texttt{collada-dom} packages, which are not included in the Fedora package repository.
You can grab source, \texttt{i386}, and \text{x86\_64} \texttt{RPM} files here: \texttt{http://www.mitsuba-renderer.org/releases}.
Afterwards, simply run
\begin{shell}
$\text{\$}$ scons
\end{shell}
inside the Mitsuba directory. In the case that you have multiple processors, you might want to parallelize the build by appending \code{-j }\emph{core count} to the command.
If all goes well, SCons should finish successfully within a few minutes:
\begin{shell}
scons: $\texttt{done}$ building targets.
\end{shell}
To be able to run the renderer from the command line, you will also have to import it into your path:
\begin{shell}
$\text{\$}$ . setpath.sh
\end{shell}
(note the period at the beginning -- this assumes that you are using \code{bash}).
\subsection{Building on Arch Linux}
You'll first need to install a number of dependencies.
First, run
\begin{shell}
$\text{\$}$ pacman -S mercurial openexr gcc xerces-c boost libjpeg libpng qt libxmu libxi mesa pcre libxml2 scons
\end{shell}
Some of the extra dependencies must be built manually:
\begin{shell}
$\text{\$}$ wget https://www.mitsuba-renderer.org/releases/contrib/archlinux/glewmx/PKGBUILD
$\text{\$}$ makepkg
$\text{\$}$ sudo pacman -U glewmx-*.xz
\end{shell}
and similar for \texttt{https://www.mitsuba-renderer.org/releases/contrib/archlin}-
\texttt{ux/collada-dom/PKGBUILD}.
Afterwards, simply run Afterwards, simply run
\begin{shell} \begin{shell}
$\text{\$}$ scons $\text{\$}$ scons

View File

@ -270,6 +270,21 @@ template<typename T, typename U> inline T union_cast(const U &val) {
return caster.t; return caster.t;
} }
/// Return a string representation of a list of objects
template<class T> std::string listToString(const std::vector<T> &vec) {
std::ostringstream oss;
oss << "{" << endl;
for (size_t i=0; i<vec.size(); ++i) {
oss << " " << indent(vec[i]->toString());
if (i != vec.size()-1)
oss << "," << endl;
else
oss << endl;
}
oss << "}";
return oss.str();
}
MTS_NAMESPACE_END MTS_NAMESPACE_END
#endif /* __UTIL_H */ #endif /* __UTIL_H */

View File

@ -356,7 +356,7 @@ void Bitmap::loadPNG(Stream *stream) {
} }
/* Error handling */ /* Error handling */
if (setjmp(png_ptr->jmpbuf)) { if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL);
if (rows) if (rows)
delete[] rows; delete[] rows;
@ -379,7 +379,8 @@ void Bitmap::loadPNG(Stream *stream) {
png_set_expand(png_ptr); // expand indexed files png_set_expand(png_ptr); // expand indexed files
newDepth = 8; newDepth = 8;
} else if (colortype == PNG_COLOR_TYPE_GRAY && bitdepth < 8) { } else if (colortype == PNG_COLOR_TYPE_GRAY && bitdepth < 8) {
png_set_gray_1_2_4_to_8(png_ptr); // convert grayscale to 8bit
png_set_expand_gray_1_2_4_to_8(png_ptr); // convert grayscale to 8bit
newDepth = 8; newDepth = 8;
} else if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { } else if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
png_set_expand(png_ptr); // transparency png_set_expand(png_ptr); // transparency
@ -590,7 +591,7 @@ void Bitmap::savePNG(Stream *stream) const {
} }
/* Error handling */ /* Error handling */
if (setjmp(png_ptr->jmpbuf)) { if (setjmp(png_jmpbuf(png_ptr))) {
png_destroy_write_struct(&png_ptr, &info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr);
Log(EError, "Error writing the PNG file"); Log(EError, "Error writing the PNG file");
} }

View File

@ -14,7 +14,7 @@ FileResolver::FileResolver() {
addPath(MTS_RESOURCE_DIR); addPath(MTS_RESOURCE_DIR);
#elif defined(__OSX__) #elif defined(__OSX__)
MTS_AUTORELEASE_BEGIN() MTS_AUTORELEASE_BEGIN()
Thread::getThread()->getFileResolver()->addPath(__ubi_bundlepath()); addPath(__ubi_bundlepath());
MTS_AUTORELEASE_END() MTS_AUTORELEASE_END()
#elif defined(WIN32) #elif defined(WIN32)
char lpFilename[1024]; char lpFilename[1024];

View File

@ -238,6 +238,10 @@ std::string Thread::toString() const {
} }
void Thread::staticInitialization() { void Thread::staticInitialization() {
#if defined(__OSX__)
__ubi_autorelease_init();
#endif
m_self = new ThreadLocal<Thread>(); m_self = new ThreadLocal<Thread>();
#if defined(__LINUX__) || defined(__OSX__) #if defined(__LINUX__) || defined(__OSX__)
m_idMutex = new Mutex(); m_idMutex = new Mutex();
@ -252,7 +256,6 @@ void Thread::staticInitialization() {
m_self->set(mainThread); m_self->set(mainThread);
#if defined(__OSX__) #if defined(__OSX__)
mainThread->m_id = 0; mainThread->m_id = 0;
__ubi_autorelease_init();
#elif defined(__LINUX__) #elif defined(__LINUX__)
m_id = 0; m_id = 0;
#endif #endif

View File

@ -359,8 +359,6 @@ void GLRenderer::endDrawingMeshes() {
} }
void GLRenderer::drawAll() { void GLRenderer::drawAll() {
if (true)
return;
GLRenderer::beginDrawingMeshes(true); GLRenderer::beginDrawingMeshes(true);
std::map<const TriMesh *, GPUGeometry *>::iterator it; std::map<const TriMesh *, GPUGeometry *>::iterator it;
if (m_capabilities->isSupported(RendererCapabilities::EBindless)) { if (m_capabilities->isSupported(RendererCapabilities::EBindless)) {

View File

@ -620,20 +620,6 @@ void Scene::serialize(Stream *stream, InstanceManager *manager) const {
manager->serialize(stream, m_netObjects[i]); manager->serialize(stream, m_netObjects[i]);
} }
template<class T> std::string listToString(const std::vector<T> &vec) {
std::ostringstream oss;
oss << "{" << endl;
for (size_t i=0; i<vec.size(); ++i) {
oss << " " << indent(vec[i]->toString());
if (i != vec.size()-1)
oss << "," << endl;
else
oss << endl;
}
oss << "}";
return oss.str();
}
std::string Scene::toString() const { std::string Scene::toString() const {
std::ostringstream oss; std::ostringstream oss;

View File

@ -332,29 +332,42 @@ public:
Log(EInfo, " eigs(M) = %s", vecToString(eigs).c_str()); Log(EInfo, " eigs(M) = %s", vecToString(eigs).c_str());
Log(EInfo, " P = %s", mtxToString(m_P).c_str()); Log(EInfo, " P = %s", mtxToString(m_P).c_str());
#endif #endif
m_kdTree = new KDTree();
} }
FlakeMedium(Stream *stream, InstanceManager *manager) FlakeMedium(Stream *stream, InstanceManager *manager)
: Medium(stream, manager) { : Medium(stream, manager) {
m_shape = static_cast<Shape *>(manager->getInstance(stream));
m_kdTree = new KDTree(); m_kdTree = new KDTree();
m_kdTree->addShape(m_shape.get()); size_t shapeCount = stream->readUInt();
m_kdTree->build(); for (size_t i=0; i<shapeCount; ++i)
addChild("", static_cast<Shape *>(manager->getInstance(stream)));
m_D = SHVector(stream); m_D = SHVector(stream);
m_sigmaS = SHVector(stream); m_sigmaS = SHVector(stream);
m_sigmaT = SHVector(stream); m_sigmaT = SHVector(stream);
m_area = stream->readFloat(); m_area = stream->readFloat();
m_rho = stream->readFloat(); m_rho = stream->readFloat();
m_frame = Frame(stream); m_frame = Frame(stream);
configure();
} }
virtual ~FlakeMedium() { virtual ~FlakeMedium() {
for (size_t i=0; i<m_shapes.size(); ++i)
m_shapes[i]->decRef();
}
void configure() {
Medium::configure();
if (m_shapes.size() == 0)
Log(EError, "This medium requires one or more Shape instance as a child");
m_kdTree->build();
m_aabb = m_kdTree->getAABB();
} }
void serialize(Stream *stream, InstanceManager *manager) const { void serialize(Stream *stream, InstanceManager *manager) const {
Medium::serialize(stream, manager); Medium::serialize(stream, manager);
manager->serialize(stream, m_shape.get()); stream->writeUInt((uint32_t) m_shapes.size());
for (size_t i=0; i<m_shapes.size(); ++i)
manager->serialize(stream, m_shapes[i]);
m_D.serialize(stream); m_D.serialize(stream);
m_sigmaS.serialize(stream); m_sigmaS.serialize(stream);
m_sigmaT.serialize(stream); m_sigmaT.serialize(stream);
@ -478,17 +491,25 @@ public:
void setParent(ConfigurableObject *parent) { void setParent(ConfigurableObject *parent) {
if (parent->getClass()->derivesFrom(Shape::m_theClass)) if (parent->getClass()->derivesFrom(Shape::m_theClass))
Log(EError, "Medium shape cannot be part of the scene"); Log(EError, "Medium cannot be a parent of a shape");
} }
void addChild(const std::string &name, ConfigurableObject *child) { void addChild(const std::string &name, ConfigurableObject *child) {
if (child->getClass()->derivesFrom(Shape::m_theClass)) { if (child->getClass()->derivesFrom(Shape::m_theClass)) {
Assert(m_shape == NULL); Shape *shape = static_cast<Shape *>(child);
m_shape = static_cast<Shape *>(child); if (shape->isCompound()) {
m_kdTree = new KDTree(); int ctr = 0;
m_kdTree->addShape(m_shape.get()); while (true) {
m_kdTree->build(); ref<Shape> childShape = shape->getElement(ctr++);
m_aabb = m_kdTree->getAABB(); if (!childShape)
break;
addChild("", childShape);
}
} else {
m_kdTree->addShape(shape);
shape->incRef();
m_shapes.push_back(shape);
}
} else { } else {
Medium::addChild(name, child); Medium::addChild(name, child);
} }
@ -499,15 +520,15 @@ public:
oss << "FlakeMedium[" << endl oss << "FlakeMedium[" << endl
<< " area = " << m_area << "," << std::endl << " area = " << m_area << "," << std::endl
<< " rho = " << m_rho << "," << std::endl << " rho = " << m_rho << "," << std::endl
<< " shape = " << indent(m_shape->toString()) << std::endl << " shapes = " << indent(listToString(m_shapes)) << std::endl
<< "]"; << "]";
return oss.str(); return oss.str();
} }
MTS_DECLARE_CLASS() MTS_DECLARE_CLASS()
private: private:
ref<Shape> m_shape;
ref<KDTree> m_kdTree; ref<KDTree> m_kdTree;
std::vector<Shape *> m_shapes;
SHVector m_D, m_sigmaS, m_sigmaT; SHVector m_D, m_sigmaS, m_sigmaT;
Float m_area, m_rho; Float m_area, m_rho;
Frame m_frame; Frame m_frame;

View File

@ -203,12 +203,16 @@ public:
m_sigmaT.convolve(absCos); m_sigmaT.convolve(absCos);
m_sigmaT *= 2; m_sigmaT *= 2;
Assert(m_sigmaT.isAzimuthallyInvariant()); Assert(m_sigmaT.isAzimuthallyInvariant());
m_kdTree = new KDTree();
} }
/* Unserialize from a binary data stream */ /* Unserialize from a binary data stream */
HeterogeneousFlakeMedium(Stream *stream, InstanceManager *manager) HeterogeneousFlakeMedium(Stream *stream, InstanceManager *manager)
: Medium(stream, manager) { : Medium(stream, manager) {
m_shape = static_cast<Shape *>(manager->getInstance(stream)); m_kdTree = new KDTree();
size_t shapeCount = stream->readUInt();
for (size_t i=0; i<shapeCount; ++i)
addChild("", static_cast<Shape *>(manager->getInstance(stream)));
m_densities = static_cast<VolumeDataSource *>(manager->getInstance(stream)); m_densities = static_cast<VolumeDataSource *>(manager->getInstance(stream));
m_albedo = static_cast<VolumeDataSource *>(manager->getInstance(stream)); m_albedo = static_cast<VolumeDataSource *>(manager->getInstance(stream));
m_orientations = static_cast<VolumeDataSource *>(manager->getInstance(stream)); m_orientations = static_cast<VolumeDataSource *>(manager->getInstance(stream));
@ -220,21 +224,20 @@ public:
m_sigmaT = SHVector(stream); m_sigmaT = SHVector(stream);
m_phaseExpansion = SHVector4D(stream); m_phaseExpansion = SHVector4D(stream);
m_samplingRecursions = stream->readInt(); m_samplingRecursions = stream->readInt();
m_kdTree = new KDTree();
if (m_shape != NULL) {
m_kdTree->addShape(m_shape.get());
m_kdTree->build();
}
configure(); configure();
} }
virtual ~HeterogeneousFlakeMedium() { virtual ~HeterogeneousFlakeMedium() {
for (size_t i=0; i<m_shapes.size(); ++i)
m_shapes[i]->decRef();
} }
/* Serialize the volume to a binary data stream */ /* Serialize the volume to a binary data stream */
void serialize(Stream *stream, InstanceManager *manager) const { void serialize(Stream *stream, InstanceManager *manager) const {
Medium::serialize(stream, manager); Medium::serialize(stream, manager);
manager->serialize(stream, m_shape.get()); stream->writeUInt((uint32_t) m_shapes.size());
for (size_t i=0; i<m_shapes.size(); ++i)
manager->serialize(stream, m_shapes[i]);
manager->serialize(stream, m_densities.get()); manager->serialize(stream, m_densities.get());
manager->serialize(stream, m_albedo.get()); manager->serialize(stream, m_albedo.get());
manager->serialize(stream, m_orientations.get()); manager->serialize(stream, m_orientations.get());
@ -270,19 +273,36 @@ public:
m_phaseFunction = new FlakePhaseFunction(m_sigmaT, m_samplingRecursions, m_phaseFunction = new FlakePhaseFunction(m_sigmaT, m_samplingRecursions,
&m_phaseExpansion, m_exponent, m_normalization, m_fiber, this); &m_phaseExpansion, m_exponent, m_normalization, m_fiber, this);
if (m_shape != NULL) if (m_shapes.size() > 0) {
m_kdTree->build();
m_aabb = m_kdTree->getAABB(); m_aabb = m_kdTree->getAABB();
else } else {
m_aabb = m_densities->getAABB(); m_aabb = m_densities->getAABB();
} }
}
void setParent(ConfigurableObject *parent) {
if (parent->getClass()->derivesFrom(Shape::m_theClass))
Log(EError, "Medium cannot be a parent of a shape");
}
void addChild(const std::string &name, ConfigurableObject *child) { void addChild(const std::string &name, ConfigurableObject *child) {
if (child->getClass()->derivesFrom(Shape::m_theClass)) { if (child->getClass()->derivesFrom(Shape::m_theClass)) {
Assert(m_shape == NULL); Shape *shape = static_cast<Shape *>(child);
m_shape = static_cast<Shape *>(child); if (shape->isCompound()) {
m_kdTree = new KDTree(); int ctr = 0;
m_kdTree->addShape(m_shape.get()); while (true) {
m_kdTree->build(); ref<Shape> childShape = shape->getElement(ctr++);
if (!childShape)
break;
addChild("", childShape);
}
} else {
m_kdTree->addShape(shape);
shape->incRef();
m_shapes.push_back(shape);
}
} else if (child->getClass()->derivesFrom(VolumeDataSource::m_theClass)) { } else if (child->getClass()->derivesFrom(VolumeDataSource::m_theClass)) {
VolumeDataSource *volume = static_cast<VolumeDataSource *>(child); VolumeDataSource *volume = static_cast<VolumeDataSource *>(child);
@ -302,7 +322,7 @@ public:
} }
Float distanceToMediumEntry(const Ray &ray) const { Float distanceToMediumEntry(const Ray &ray) const {
if (m_shape != NULL) { if (m_shapes.size() != 0) {
Ray r(ray, Epsilon, std::numeric_limits<Float>::infinity()); Ray r(ray, Epsilon, std::numeric_limits<Float>::infinity());
Intersection its; Intersection its;
if (!m_kdTree->rayIntersect(r, its)) if (!m_kdTree->rayIntersect(r, its))
@ -320,7 +340,7 @@ public:
} }
Float distanceToMediumExit(const Ray &ray) const { Float distanceToMediumExit(const Ray &ray) const {
if (m_shape != NULL) { if (m_shapes.size() != 0) {
Ray r(ray, Epsilon, std::numeric_limits<Float>::infinity()); Ray r(ray, Epsilon, std::numeric_limits<Float>::infinity());
Intersection its; Intersection its;
if (!m_kdTree->rayIntersect(r, its)) if (!m_kdTree->rayIntersect(r, its))
@ -528,10 +548,10 @@ public:
std::string toString() const { std::string toString() const {
std::ostringstream oss; std::ostringstream oss;
oss << "HeterogeneousFlakeMedium[" << endl oss << "HeterogeneousFlakeMedium[" << endl
<< " albedo=" << indent(m_albedo.toString()) << endl << " albedo=" << indent(m_albedo.toString()) << "," << endl
<< " orientations=" << indent(m_orientations.toString()) << endl << " orientations=" << indent(m_orientations.toString()) << "," << endl
<< " densities=" << indent(m_densities.toString()) << endl << " densities=" << indent(m_densities.toString()) << "," << endl
<< " shape =" << indent(m_shape.toString()) << endl << " shapes = " << indent(listToString(m_shapes)) << endl
<< "]"; << "]";
return oss.str(); return oss.str();
} }
@ -540,8 +560,8 @@ private:
ref<VolumeDataSource> m_densities; ref<VolumeDataSource> m_densities;
ref<VolumeDataSource> m_albedo; ref<VolumeDataSource> m_albedo;
ref<VolumeDataSource> m_orientations; ref<VolumeDataSource> m_orientations;
ref<Shape> m_shape;
ref<KDTree> m_kdTree; ref<KDTree> m_kdTree;
std::vector<Shape *> m_shapes;
Float m_stepSize; Float m_stepSize;
/* Flake model-related */ /* Flake model-related */
SHVector m_D, m_sigmaT; SHVector m_D, m_sigmaT;

View File

@ -34,32 +34,35 @@ class HeterogeneousStencilMedium : public Medium {
public: public:
HeterogeneousStencilMedium(const Properties &props) HeterogeneousStencilMedium(const Properties &props)
: Medium(props) { : Medium(props) {
m_kdTree = new KDTree();
m_stepSize = props.getFloat("stepSize", 0); m_stepSize = props.getFloat("stepSize", 0);
} }
/* Unserialize from a binary data stream */ /* Unserialize from a binary data stream */
HeterogeneousStencilMedium(Stream *stream, InstanceManager *manager) HeterogeneousStencilMedium(Stream *stream, InstanceManager *manager)
: Medium(stream, manager) { : Medium(stream, manager) {
m_shape = static_cast<Shape *>(manager->getInstance(stream)); m_kdTree = new KDTree();
size_t shapeCount = stream->readUInt();
for (size_t i=0; i<shapeCount; ++i)
addChild("", static_cast<Shape *>(manager->getInstance(stream)));
m_densities = static_cast<VolumeDataSource *>(manager->getInstance(stream)); m_densities = static_cast<VolumeDataSource *>(manager->getInstance(stream));
m_albedo = static_cast<VolumeDataSource *>(manager->getInstance(stream)); m_albedo = static_cast<VolumeDataSource *>(manager->getInstance(stream));
m_orientations = static_cast<VolumeDataSource *>(manager->getInstance(stream)); m_orientations = static_cast<VolumeDataSource *>(manager->getInstance(stream));
m_stepSize = stream->readFloat(); m_stepSize = stream->readFloat();
m_kdTree = new KDTree();
if (m_shape != NULL) {
m_kdTree->addShape(m_shape.get());
m_kdTree->build();
}
configure(); configure();
} }
virtual ~HeterogeneousStencilMedium() { virtual ~HeterogeneousStencilMedium() {
for (size_t i=0; i<m_shapes.size(); ++i)
m_shapes[i]->decRef();
} }
/* Serialize the volume to a binary data stream */ /* Serialize the volume to a binary data stream */
void serialize(Stream *stream, InstanceManager *manager) const { void serialize(Stream *stream, InstanceManager *manager) const {
Medium::serialize(stream, manager); Medium::serialize(stream, manager);
manager->serialize(stream, m_shape.get()); stream->writeUInt((uint32_t) m_shapes.size());
for (size_t i=0; i<m_shapes.size(); ++i)
manager->serialize(stream, m_shapes[i]);
manager->serialize(stream, m_densities.get()); manager->serialize(stream, m_densities.get());
manager->serialize(stream, m_albedo.get()); manager->serialize(stream, m_albedo.get());
manager->serialize(stream, m_orientations.get()); manager->serialize(stream, m_orientations.get());
@ -75,11 +78,12 @@ public:
if (m_orientations.get() == NULL) if (m_orientations.get() == NULL)
Log(EError, "No orientations specified!"); Log(EError, "No orientations specified!");
if (m_shapes.size() != 0) {
if (m_shape != NULL) m_kdTree->build();
m_aabb = m_kdTree->getAABB(); m_aabb = m_kdTree->getAABB();
else } else {
m_aabb = m_densities->getAABB(); m_aabb = m_densities->getAABB();
}
if (m_stepSize == 0) { if (m_stepSize == 0) {
m_stepSize = std::min(std::min( m_stepSize = std::min(std::min(
@ -94,11 +98,20 @@ public:
void addChild(const std::string &name, ConfigurableObject *child) { void addChild(const std::string &name, ConfigurableObject *child) {
if (child->getClass()->derivesFrom(Shape::m_theClass)) { if (child->getClass()->derivesFrom(Shape::m_theClass)) {
Assert(m_shape == NULL); Shape *shape = static_cast<Shape *>(child);
m_shape = static_cast<Shape *>(child); if (shape->isCompound()) {
m_kdTree = new KDTree(); int ctr = 0;
m_kdTree->addShape(m_shape.get()); while (true) {
m_kdTree->build(); ref<Shape> childShape = shape->getElement(ctr++);
if (!childShape)
break;
addChild("", childShape);
}
} else {
m_kdTree->addShape(shape);
shape->incRef();
m_shapes.push_back(shape);
}
} else if (child->getClass()->derivesFrom(VolumeDataSource::m_theClass)) { } else if (child->getClass()->derivesFrom(VolumeDataSource::m_theClass)) {
VolumeDataSource *volume = static_cast<VolumeDataSource *>(child); VolumeDataSource *volume = static_cast<VolumeDataSource *>(child);
@ -118,7 +131,7 @@ public:
} }
Float distanceToMediumEntry(const Ray &ray) const { Float distanceToMediumEntry(const Ray &ray) const {
if (m_shape != NULL) { if (m_shapes.size() != 0) {
Ray r(ray, Epsilon, std::numeric_limits<Float>::infinity()); Ray r(ray, Epsilon, std::numeric_limits<Float>::infinity());
Intersection its; Intersection its;
if (!m_kdTree->rayIntersect(r, its)) if (!m_kdTree->rayIntersect(r, its))
@ -136,7 +149,7 @@ public:
} }
Float distanceToMediumExit(const Ray &ray) const { Float distanceToMediumExit(const Ray &ray) const {
if (m_shape != NULL) { if (m_shapes.size() != 0) {
Ray r(ray, Epsilon, std::numeric_limits<Float>::infinity()); Ray r(ray, Epsilon, std::numeric_limits<Float>::infinity());
Intersection its; Intersection its;
if (!m_kdTree->rayIntersect(r, its)) if (!m_kdTree->rayIntersect(r, its))
@ -322,8 +335,7 @@ public:
oss << "HeterogeneousStencilMedium[" << endl oss << "HeterogeneousStencilMedium[" << endl
<< " albedo=" << indent(m_albedo.toString()) << endl << " albedo=" << indent(m_albedo.toString()) << endl
<< " orientations=" << indent(m_orientations.toString()) << endl << " orientations=" << indent(m_orientations.toString()) << endl
<< " densities=" << indent(m_densities.toString()) << endl << " densities=" << indent(m_densities.toString())
<< " shape =" << indent(m_shape.toString()) << endl
<< "]"; << "]";
return oss.str(); return oss.str();
} }
@ -332,8 +344,8 @@ private:
ref<VolumeDataSource> m_densities; ref<VolumeDataSource> m_densities;
ref<VolumeDataSource> m_albedo; ref<VolumeDataSource> m_albedo;
ref<VolumeDataSource> m_orientations; ref<VolumeDataSource> m_orientations;
ref<Shape> m_shape;
ref<KDTree> m_kdTree; ref<KDTree> m_kdTree;
std::vector<Shape *> m_shapes;
Float m_stepSize; Float m_stepSize;
}; };

View File

@ -66,14 +66,15 @@ public:
coeffs[i] = m_sigmaT[i]; coeffs[i] = m_sigmaT[i];
m_maxExpDist = new MaxExpDist(coeffs); m_maxExpDist = new MaxExpDist(coeffs);
m_kdTree = new KDTree();
} }
HomogeneousMedium(Stream *stream, InstanceManager *manager) HomogeneousMedium(Stream *stream, InstanceManager *manager)
: Medium(stream, manager) { : Medium(stream, manager) {
m_shape = static_cast<Shape *>(manager->getInstance(stream));
m_kdTree = new KDTree(); m_kdTree = new KDTree();
m_kdTree->addShape(m_shape.get()); size_t shapeCount = stream->readUInt();
m_kdTree->build(); for (size_t i=0; i<shapeCount; ++i)
addChild("", static_cast<Shape *>(manager->getInstance(stream)));
m_channel = stream->readInt(); m_channel = stream->readInt();
m_strategy = (ESamplingStrategy) stream->readInt(); m_strategy = (ESamplingStrategy) stream->readInt();
m_sigma = stream->readFloat(); m_sigma = stream->readFloat();
@ -82,16 +83,21 @@ public:
for (int i=0; i<SPECTRUM_SAMPLES; ++i) for (int i=0; i<SPECTRUM_SAMPLES; ++i)
coeffs[i] = m_sigmaT[i]; coeffs[i] = m_sigmaT[i];
configure();
m_maxExpDist = new MaxExpDist(coeffs); m_maxExpDist = new MaxExpDist(coeffs);
} }
virtual ~HomogeneousMedium() { virtual ~HomogeneousMedium() {
for (size_t i=0; i<m_shapes.size(); ++i)
m_shapes[i]->decRef();
delete m_maxExpDist; delete m_maxExpDist;
} }
void serialize(Stream *stream, InstanceManager *manager) const { void serialize(Stream *stream, InstanceManager *manager) const {
Medium::serialize(stream, manager); Medium::serialize(stream, manager);
manager->serialize(stream, m_shape.get()); stream->writeUInt((uint32_t) m_shapes.size());
for (size_t i=0; i<m_shapes.size(); ++i)
manager->serialize(stream, m_shapes[i]);
stream->writeInt(m_channel); stream->writeInt(m_channel);
stream->writeInt(m_strategy); stream->writeInt(m_strategy);
stream->writeFloat(m_sigma); stream->writeFloat(m_sigma);
@ -99,8 +105,10 @@ public:
void configure() { void configure() {
Medium::configure(); Medium::configure();
if (m_shape.get() == NULL) if (m_shapes.size() == 0)
Log(EError, "This medium requires a Shape instance as a child "); Log(EError, "This medium requires one or more Shape instance as a child");
m_kdTree->build();
m_aabb = m_kdTree->getAABB();
} }
bool isInside(const Ray &r) const { bool isInside(const Ray &r) const {
@ -267,17 +275,25 @@ public:
void setParent(ConfigurableObject *parent) { void setParent(ConfigurableObject *parent) {
if (parent->getClass()->derivesFrom(Shape::m_theClass)) if (parent->getClass()->derivesFrom(Shape::m_theClass))
Log(EError, "Medium shape cannot be part of the scene"); Log(EError, "Medium cannot be a parent of a shape");
} }
void addChild(const std::string &name, ConfigurableObject *child) { void addChild(const std::string &name, ConfigurableObject *child) {
if (child->getClass()->derivesFrom(Shape::m_theClass)) { if (child->getClass()->derivesFrom(Shape::m_theClass)) {
Assert(m_shape == NULL); Shape *shape = static_cast<Shape *>(child);
m_shape = static_cast<Shape *>(child); if (shape->isCompound()) {
m_kdTree = new KDTree(); int ctr = 0;
m_kdTree->addShape(m_shape.get()); while (true) {
m_kdTree->build(); ref<Shape> childShape = shape->getElement(ctr++);
m_aabb = m_kdTree->getAABB(); if (!childShape)
break;
addChild("", childShape);
}
} else {
m_kdTree->addShape(shape);
shape->incRef();
m_shapes.push_back(shape);
}
} else { } else {
Medium::addChild(name, child); Medium::addChild(name, child);
} }
@ -290,15 +306,15 @@ public:
<< " sigmaS = " << m_sigmaS.toString() << "," << std::endl << " sigmaS = " << m_sigmaS.toString() << "," << std::endl
<< " sigmaT = " << m_sigmaT.toString() << "," << std::endl << " sigmaT = " << m_sigmaT.toString() << "," << std::endl
<< " phase = " << indent(m_phaseFunction->toString()) << "," << std::endl << " phase = " << indent(m_phaseFunction->toString()) << "," << std::endl
<< " shape = " << indent(m_shape->toString()) << std::endl << " shapes = " << indent(listToString(m_shapes)) << std::endl
<< "]"; << "]";
return oss.str(); return oss.str();
} }
MTS_DECLARE_CLASS() MTS_DECLARE_CLASS()
private: private:
ref<Shape> m_shape;
ref<KDTree> m_kdTree; ref<KDTree> m_kdTree;
std::vector<Shape *> m_shapes;
int m_channel; int m_channel;
Float m_sigma; Float m_sigma;
ESamplingStrategy m_strategy; ESamplingStrategy m_strategy;

View File

@ -54,7 +54,8 @@ void ImportDialog::changeEvent(QEvent *e) {
void ImportDialog::on_inputBrowse_clicked(bool checked) { void ImportDialog::on_inputBrowse_clicked(bool checked) {
QFileDialog dialog(this); QFileDialog dialog(this);
dialog.setNameFilter(tr("COLLADA 1.4 scenes (*.dae *.zae);; Wavefront OBJ scenes (*.obj)")); dialog.setNameFilter(tr("All supported formats (*.dae *.zae *.obj);;"
"COLLADA 1.4 scenes (*.dae *.zae);; Wavefront OBJ scenes (*.obj)"));
dialog.setAcceptMode(QFileDialog::AcceptOpen); dialog.setAcceptMode(QFileDialog::AcceptOpen);
dialog.setViewMode(QFileDialog::Detail); dialog.setViewMode(QFileDialog::Detail);
dialog.setWindowModality(Qt::ApplicationModal); dialog.setWindowModality(Qt::ApplicationModal);

View File

@ -225,7 +225,7 @@ MainWindow::MainWindow(QWidget *parent) :
/* Submit crash reports on OSX */ /* Submit crash reports on OSX */
QDir crashDir = QDir::home(); QDir crashDir = QDir::home();
crashDir.cd("Library/Logs/CrashReporter"); crashDir.cd("Library/Logs/CrashReporter");
QFileInfoList crashReports = crashDir.entryInfoList(QStringList("qtgui_*"), QFileInfoList crashReports = crashDir.entryInfoList(QStringList("mtsgui_*"),
QDir::Files, QDir::Name); QDir::Files, QDir::Name);
if (crashReports.size() > 0) { if (crashReports.size() > 0) {
@ -292,6 +292,15 @@ MainWindow::MainWindow(QWidget *parent) :
QMessageBox::information(this, tr("Crash reporter"), QMessageBox::information(this, tr("Crash reporter"),
tr("All crash reports have been submitted. Thank you!"), tr("All crash reports have been submitted. Thank you!"),
QMessageBox::Ok); QMessageBox::Ok);
} else {
for (int i=0; i<crashReports.size(); ++i) {
QFile file(crashReports[i].absoluteFilePath());
if (!file.remove()) {
QMessageBox::critical(this, tr("Unable to submitted crash report"),
tr("Unable to delete a crash report -- please check the file permissions in ~/Library/Logs/CrashReporter."), QMessageBox::Ok);
break;
}
}
} }
} }
#endif #endif
@ -534,7 +543,8 @@ void MainWindow::onProgressMessage(const RenderJob *job, const QString &name,
void MainWindow::on_actionOpen_triggered() { void MainWindow::on_actionOpen_triggered() {
QFileDialog *dialog = new QFileDialog(this, Qt::Sheet); QFileDialog *dialog = new QFileDialog(this, Qt::Sheet);
dialog->setNameFilter(tr("Mitsuba scenes (*.xml);;EXR images (*.exr)")); dialog->setNameFilter(tr("All supported formats (*.xml *.exr);;"
"Mitsuba scenes (*.xml);;EXR images (*.exr)"));
dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setAcceptMode(QFileDialog::AcceptOpen); dialog->setAcceptMode(QFileDialog::AcceptOpen);
dialog->setViewMode(QFileDialog::Detail); dialog->setViewMode(QFileDialog::Detail);
@ -1208,7 +1218,8 @@ inline float toSRGB(float value) {
void MainWindow::on_actionExportImage_triggered() { void MainWindow::on_actionExportImage_triggered() {
SceneContext *ctx = m_context[ui->tabBar->currentIndex()]; SceneContext *ctx = m_context[ui->tabBar->currentIndex()];
QFileDialog dialog(this, tr("Export image .."), QFileDialog dialog(this, tr("Export image .."),
"", tr("Linear EXR Image (*.exr);; Tonemapped 8-bit PNG Image (*.png)")); "", tr("All supported formats (*.exr *.png);;Linear EXR Image (*.exr)"
";; Tonemapped 8-bit PNG Image (*.png)"));
QSettings settings("mitsuba-renderer.org", "qtgui"); QSettings settings("mitsuba-renderer.org", "qtgui");
dialog.setViewMode(QFileDialog::Detail); dialog.setViewMode(QFileDialog::Detail);

Binary file not shown.

Binary file not shown.

Binary file not shown.