merging with animation-aware branch

metadata
Wenzel Jakob 2010-11-19 16:59:19 +01:00
commit e104b7bdb4
25 changed files with 195 additions and 127 deletions

View File

@ -329,7 +329,7 @@ librender = renderEnv.SharedLibrary('src/librender/mitsuba-render', [
'src/librender/preview.cpp', 'src/librender/photonmap.cpp',
'src/librender/gatherproc.cpp', 'src/librender/mipmap3d.cpp',
'src/librender/volume.cpp', 'src/librender/vpl.cpp',
'src/librender/shader.cpp', 'src/librender/shandler.cpp',
'src/librender/shader.cpp', 'src/librender/scenehandler.cpp',
'src/librender/intersection.cpp', 'src/librender/track.cpp'
])

View File

@ -100,20 +100,6 @@ inherent relation that links them to another object. For instance, BSDFs are usu
they appear as a child object of a shape. Similarly, the sampler and film affect the way in which
rays are generated from the camera and how it records the resulting radiance samples, hence they are nested inside it.
Note that you should always put properties \emph{before} nested child objects, otherwise you'll see something like the following slightly cryptic
XML validation error. For instance,
\begin{xml}
...
<shape type="obj">
<bsdf type="phong"/>
<string name="filename" value="lucy.obj"/>
</shape>
...
\end{xml}
fails with this message:
\begin{shell}
Caught a critical exeption: 2010-08-11 03:23:31 ERROR main [src/mitsuba/shandler.cpp:359] Error in file "/home/wenzel/mitsuba/test.xml" (line 63): Element 'string' is not valid $\texttt{for}$ content model: '(((integer|float|point|vector|boolean|transform|string|spectrum|rgb)|blackbody),((bsdf|subsurface|ref)|luminaire))'
\end{shell}
\subsection{Property types}
This section documents all of the ways in which properties can be supplied to objects. If you are more
interested in knowing which properties a certain plugin accepts, you should look at the next section instead.

View File

@ -5,7 +5,7 @@
<xsd:complexType>
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="camera" type="camera"/>
<xsd:element name="texture" type="object"/>
<xsd:element name="texture" type="texture"/>
<xsd:element name="bsdf" type="bsdf"/>
<xsd:element name="integrator" type="integrator"/>
<xsd:element name="luminaire" type="luminaire"/>
@ -29,9 +29,9 @@
</xsd:element>
<!-- Generic Object -->
<xsd:complexType name="object">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<!-- Usual attributes -->
<xsd:group name="objectGroup">
<!-- Allow all property types -->
<xsd:choice>
<xsd:element name="integer" type="integer"/>
<xsd:element name="float" type="float"/>
<xsd:element name="point" type="point"/>
@ -44,12 +44,27 @@
<xsd:element name="srgb" type="string"/>
<xsd:element name="blackbody" type="blackbody"/>
</xsd:choice>
</xsd:group>
<xsd:complexType name="objectBase">
<xsd:attribute name="type" type="xsd:string" use="required"/>
<xsd:attribute name="name" type="xsd:string"/>
<xsd:attribute name="id" type="xsd:string"/>
</xsd:complexType>
<!-- Object reference -->
<xsd:complexType name="object">
<xsd:complexContent>
<xsd:extension base="objectBase">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:group ref="objectGroup"/>
</xsd:choice>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<!-- REFERENCE -->
<xsd:complexType name="reference">
<xsd:attribute name="id" type="xsd:string" use="required"/>
<xsd:attribute name="name" type="xsd:string"/>
@ -58,8 +73,9 @@
<!-- CAMERA Element -->
<xsd:complexType name="camera">
<xsd:complexContent>
<xsd:extension base="object">
<xsd:extension base="objectBase">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:group ref="objectGroup"/>
<xsd:element name="sampler" type="object"/>
<xsd:element name="film" type="film"/>
</xsd:choice>
@ -70,8 +86,9 @@
<!-- INTEGRATOR Element -->
<xsd:complexType name="integrator">
<xsd:complexContent>
<xsd:extension base="object">
<xsd:extension base="objectBase">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:group ref="objectGroup"/>
<xsd:element name="integrator" type="integrator"/>
<xsd:element name="sampler" type="object"/>
</xsd:choice>
@ -82,9 +99,10 @@
<!-- LUMINAIRE Element -->
<xsd:complexType name="luminaire">
<xsd:complexContent>
<xsd:extension base="object">
<xsd:extension base="objectBase">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="texture" type="object"/>
<xsd:group ref="objectGroup"/>
<xsd:element name="texture" type="texture"/>
<xsd:element name="luminaire" type="luminaire"/>
</xsd:choice>
</xsd:extension>
@ -95,8 +113,9 @@
<!-- SHAPE Element -->
<xsd:complexType name="shape">
<xsd:complexContent>
<xsd:extension base="object">
<xsd:extension base="objectBase">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:group ref="objectGroup"/>
<xsd:element name="bsdf" type="bsdf"/>
<xsd:element name="subsurface" type="object"/>
<xsd:element name="ref" type="reference"/>
@ -110,12 +129,12 @@
<!-- VOLUMEREGION Element -->
<xsd:complexType name="medium">
<xsd:complexContent>
<xsd:extension base="object">
<xsd:extension base="objectBase">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:group ref="objectGroup"/>
<xsd:element name="shape" type="shape"/>
<xsd:element name="volume" type="object"/>
<xsd:element name="phase" type="phase"/>
<xsd:element name="ref" type="reference"/>
</xsd:choice>
</xsd:extension>
</xsd:complexContent>
@ -124,9 +143,10 @@
<!-- BSDF Element -->
<xsd:complexType name="bsdf">
<xsd:complexContent>
<xsd:extension base="object">
<xsd:extension base="objectBase">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="texture" type="object"/>
<xsd:group ref="objectGroup"/>
<xsd:element name="texture" type="texture"/>
<xsd:element name="bsdf" type="bsdf"/>
<xsd:element name="ref" type="reference"/>
</xsd:choice>
@ -134,24 +154,41 @@
</xsd:complexContent>
</xsd:complexType>
<!-- Phase Element -->
<xsd:complexType name="phase">
<!-- TEXTURE Element -->
<xsd:complexType name="texture">
<xsd:complexContent>
<xsd:extension base="object"/>
</xsd:complexContent>
</xsd:complexType>
<!-- Film Element -->
<xsd:complexType name="film">
<xsd:complexContent>
<xsd:extension base="object">
<xsd:extension base="objectBase">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="rfilter" type="object"/>
<xsd:group ref="objectGroup"/>
<xsd:element name="texture" type="texture"/>
<xsd:element name="ref" type="reference"/>
</xsd:choice>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<!-- PHASE Element -->
<xsd:complexType name="phase">
<xsd:complexContent>
<xsd:extension base="objectBase">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:group ref="objectGroup"/>
</xsd:choice>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<!-- FILM Element -->
<xsd:complexType name="film">
<xsd:complexContent>
<xsd:extension base="objectBase">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:group ref="objectGroup"/>
<xsd:element name="rfilter" type="object"/>
</xsd:choice>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
<!-- Types and parameters -->
<xsd:simpleType name="integerType">
@ -196,15 +233,16 @@
</xsd:union>
</xsd:simpleType>
<xsd:complexType name="float">
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="value" type="doubleType" use="required"/>
</xsd:complexType>
<xsd:complexType name="integer">
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="value" type="integerType" use="required"/>
</xsd:complexType>
<xsd:complexType name="boolean">
<xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="value" type="booleanType" use="required"/>

View File

@ -1141,28 +1141,14 @@ void loadCamera(ColladaContext &ctx, Transform transform, domCamera &camera) {
ctx.os << "\t<camera id=\"" << identifier << "\" type=\"perspective\">" << endl;
if (persp->getXfov().cast()) {
Float xFov = (Float) persp->getXfov()->getValue();
if (std::abs(xFov-1.0f) < Epsilon && ctx.cvt->m_fov == -1) {
SLog(EWarn, "Found the suspicious field of view value \"1.0\", which is likely due to a bug in Blender 2.5"
" - setting to 45deg. Please use the \"-f\" parameter to override this.");
xFov = 45.0f;
}
Float yFov = radToDeg(2 * std::atan(std::tan(degToRad(xFov)/2) / aspect));
if (ctx.cvt->m_fov != -1)
xFov = yFov = ctx.cvt->m_fov;
if (aspect <= 1.0f)
ctx.os << "\t\t<float name=\"fov\" value=\"" << xFov << "\"/>" << endl;
else
ctx.os << "\t\t<float name=\"fov\" value=\"" << yFov << "\"/>" << endl;
} else if (persp->getYfov().cast()) {
Float yFov = (Float) persp->getYfov()->getValue();
if (std::abs(yFov-1.0) < Epsilon && ctx.cvt->m_fov == -1) {
SLog(EWarn, "Found the suspicious field of view value \"1.0\", which is likely due to a bug in Blender 2.5"
" - setting to 45deg. Please use the \"-f\" parameter to override this.");
yFov = 45.0f;
}
Float xFov = radToDeg(2 * std::atan(std::tan(degToRad(yFov)/2) * aspect));
if (ctx.cvt->m_fov != -1)
xFov = yFov = ctx.cvt->m_fov;
if (aspect > 1.0f)
ctx.os << "\t\t<float name=\"fov\" value=\"" << yFov << "\"/>" << endl;
else
@ -1178,7 +1164,7 @@ void loadCamera(ColladaContext &ctx, Transform transform, domCamera &camera) {
ctx.os << "\t\t\t<matrix value=\"" << matrixValues.substr(0, matrixValues.length()-1) << "\"/>" << endl;
ctx.os << "\t\t</transform>" << endl << endl;
ctx.os << "\t\t<sampler id=\"sampler\" type=\"ldsampler\">" << endl;
ctx.os << "\t\t\t<integer name=\"sampleCount\" value=\"" << ctx.cvt->m_samplesPerPixel << "\"/>" << endl;
ctx.os << "\t\t\t<integer name=\"sampleCount\" value=\"4\"/>" << endl;
ctx.os << "\t\t</sampler>" << endl << endl;
ctx.os << "\t\t<film id=\"film\" type=\"" << ctx.cvt->m_filmType << "\">" << endl;
ctx.os << "\t\t\t<integer name=\"width\" value=\"" << xres << "\"/>" << endl;
@ -1619,6 +1605,7 @@ void GeometryConverter::convertCollada(const fs::path &inputFile,
ctx.cvt = this;
ctx.trackIndex = 0;
if (m_importMaterials) {
domLibrary_images_Array &libraryImages = document->getLibrary_images_array();
for (size_t i=0; i<libraryImages.getCount(); ++i) {
domImage_Array &images = libraryImages[i]->getImage_array();
@ -1632,7 +1619,9 @@ void GeometryConverter::convertCollada(const fs::path &inputFile,
for (size_t j=0; j<materials.getCount(); ++j)
loadMaterial(ctx, *materials.get(j));
}
}
if (m_importAnimations) {
domLibrary_animations_Array &libraryAnimations = document->getLibrary_animations_array();
for (size_t i=0; i<libraryAnimations.getCount(); ++i) {
domAnimation_Array &animations = libraryAnimations[i]->getAnimation_array();
@ -1640,6 +1629,7 @@ void GeometryConverter::convertCollada(const fs::path &inputFile,
loadAnimation(ctx, *animations[j]);
}
mergeRotations(ctx);
}
for (size_t i=0; i<nodes.getCount(); ++i)
computeRefCounts(ctx, *nodes[i]);

View File

@ -195,9 +195,11 @@ void GeometryConverter::convert(const fs::path &inputFile,
if (id != "" && nodeMap.find(id) != nodeMap.end()) {
DOMNode *node = nodeMap[id], *parent = node->getParentNode();
if (strcmp(nodeName, "append") == 0) {
DOMNode *node = nodeMap[id];
for (DOMNode *child2 = child->getFirstChild(); child2 != 0; child2=child2->getNextSibling())
node->insertBefore(doc->importNode(child2, true), NULL);
} else if (strcmp(nodeName, "prepend") == 0) {
for (DOMNode *child2 = child->getFirstChild(); child2 != 0; child2=child2->getNextSibling())
node->insertBefore(doc->importNode(child2, true), node->getFirstChild());
} else if (parent == insertBeforeNode->getParentNode()) {
parent->removeChild(node);
docRoot->insertBefore(doc->importNode(child, true), insertBeforeNode);
@ -212,10 +214,13 @@ void GeometryConverter::convert(const fs::path &inputFile,
}
DOMLSSerializer *serializer = impl->createLSSerializer();
DOMConfiguration *serConf(serializer->getDomConfig());
DOMLSOutput *output = impl->createLSOutput();
DOMConfiguration *serConf = serializer->getDomConfig();
serConf->setParameter(XMLUni::fgDOMErrorHandler, &errorHandler);
if (serConf->canSetParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true))
serConf->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true);
if (serConf->canSetParameter(XMLUni::fgDOMWRTXercesPrettyPrint, true))
serConf->setParameter(XMLUni::fgDOMWRTXercesPrettyPrint, true);
DOMLSOutput *output = impl->createLSOutput();
XMLFormatTarget *target = new LocalFileFormatTarget(outputFile.file_string().c_str());
output->setByteStream(target);
serializer->write(doc, output);

View File

@ -26,10 +26,10 @@ public:
m_srgb = false;
m_mapSmallerSide = true;
m_xres = m_yres = -1;
m_samplesPerPixel = 8;
m_fov = -1;
m_filmType = "exrfilm";
m_packGeometry = true;
m_importMaterials = true;
m_importAnimations = false;
}
void convert(const fs::path &inputFile,
@ -42,9 +42,9 @@ public:
inline void setSRGB(bool srgb) { m_srgb = srgb; }
inline void setMapSmallerSide(bool mapSmallerSide) { m_mapSmallerSide = mapSmallerSide; }
inline void setResolution(int xres, int yres) { m_xres = xres; m_yres = yres; }
inline void setSamplesPerPixel(int samplesPerPixel) { m_samplesPerPixel = samplesPerPixel; }
inline void setPackGeometry(bool packGeometry) { m_packGeometry = packGeometry; }
inline void setFov(Float fov) { m_fov = fov; }
inline void setImportMaterials(bool importMaterials) { m_importMaterials = importMaterials; }
inline void setImportAnimations(bool importAnimations) { m_importAnimations = importAnimations; }
inline void setFilmType(const std::string &filmType) { m_filmType = filmType; }
inline const fs::path &getFilename() const { return m_filename; }
private:
@ -56,8 +56,8 @@ private:
const fs::path &meshesDirectory);
public:
bool m_srgb, m_mapSmallerSide;
int m_xres, m_yres, m_samplesPerPixel;
Float m_fov;
bool m_importMaterials, m_importAnimations;
int m_xres, m_yres;
fs::path m_filename, m_outputDirectory;
std::string m_filmType;
ref<FileStream> m_geometryFile;

View File

@ -54,13 +54,13 @@ void help() {
<< " -h Display this help text" << endl << endl
<< " -a p1;p2;.. Add one or more entries to the resource search path" << endl << endl
<< " -v Be more verbose" << endl << endl
<< " -p <num> Use the specified number of samples per pixel." << endl << endl
<< " -s Assume that colors are in sRGB space." << endl << endl
<< " -m Map the larger image side to the full field of view" << endl << endl
<< " -z Import animations" << endl << endl
<< " -y Don't pack all geometry data into a single file" << endl << endl
<< " -n Don't import any materials (an adjustments file will be necessary)" << endl << endl
<< " -l <type> Override the type of film (e.g. 'exrfilm', 'pngfilm', ..)" << endl << endl
<< " -r <w>x<h> Override the image resolution to e.g. 1920x1080" << endl << endl
<< " -f <fov> Override the field of view to the given value in degrees." << endl << endl
<< "Please see the documentation for more information." << endl;
}
@ -68,16 +68,15 @@ int colladaMain(int argc, char **argv) {
bool srgb = false, mapSmallerSide = true;
char optchar, *end_ptr = NULL;
int xres = -1, yres = -1;
int samplesPerPixel = 8;
std::string filmType = "exrfilm";
Float fov = -1;
FileResolver *fileResolver = Thread::getThread()->getFileResolver();
ELogLevel logLevel = EInfo;
bool packGeometry = true;
bool packGeometry = true, importMaterials = true,
importAnimations = false;
optind = 1;
while ((optchar = getopt(argc, argv, "svyhmr:a:p:f:l:")) != -1) {
while ((optchar = getopt(argc, argv, "snzvyhmr:a:l:")) != -1) {
switch (optchar) {
case 'a': {
std::vector<std::string> paths = tokenize(optarg, ";");
@ -91,10 +90,11 @@ int colladaMain(int argc, char **argv) {
case 'm':
mapSmallerSide = false;
break;
case 'p':
samplesPerPixel = strtol(optarg, &end_ptr, 10);
if (*end_ptr != '\0')
SLog(EError, "Invalid number of samples per pixel!");
case 'n':
importMaterials = false;
break;
case 'z':
importAnimations = true;
break;
case 'v':
logLevel = EDebug;
@ -105,11 +105,6 @@ int colladaMain(int argc, char **argv) {
case 'y':
packGeometry = false;
break;
case 'f':
fov = (Float) strtod(optarg, &end_ptr);
if (*end_ptr != '\0')
SLog(EError, "Invalid field of view value!");
break;
case 'r': {
std::vector<std::string> tokens = tokenize(optarg, "x");
if (tokens.size() != 2)
@ -140,9 +135,9 @@ int colladaMain(int argc, char **argv) {
ConsoleGeometryConverter converter;
converter.setSRGB(srgb);
converter.setResolution(xres, yres);
converter.setImportMaterials(importMaterials);
converter.setImportAnimations(importAnimations);
converter.setMapSmallerSide(mapSmallerSide);
converter.setSamplesPerPixel(samplesPerPixel);
converter.setFov(fov);
converter.setPackGeometry(packGeometry);
converter.setFilmType(filmType);

View File

@ -154,7 +154,7 @@ void GeometryConverter::convertOBJ(const fs::path &inputFile,
std::string buf, line;
std::set<std::string> mtlList;
while (is >> buf) {
if (buf == "mtllib") {
if (buf == "mtllib" && m_importMaterials) {
std::getline(is, line);
std::string mtlName = trim(line.substr(1, line.length()-1));
ref<FileResolver> fRes = Thread::getThread()->getFileResolver()->clone();

View File

@ -25,7 +25,7 @@ Camera::Camera(const Properties &props)
: ConfigurableObject(props), m_properties(props) {
m_cameraToWorld = props.getTransform("toWorld", Transform());
m_shutterOpen = props.getFloat("shutterOpen", 0.0f);
m_shutterClose = props.getFloat("shutterClose", 5.0f);
m_shutterClose = props.getFloat("shutterClose", 0.0f);
if (m_shutterOpen > m_shutterClose)
Log(EError, "Shutter opening time must be less than "
"or equal to the shutter closing time!");

View File

@ -68,13 +68,14 @@ void PreviewWorker::processIncoherent(const WorkUnit *workUnit, WorkResult *work
Vector toVPL;
Ray primary, secondary;
int numRays = 0;
float shutterOpen = m_scene->getCamera()->getShutterOpen();
for (int y=sy; y<ey; ++y) {
for (int x=sx; x<ex; ++x) {
/* Generate a camera ray without normalization */
primary = Ray(m_cameraO, m_cameraTL
+ m_cameraDx * (Float) x
+ m_cameraDy * (Float) y, 0.0f);
+ m_cameraDy * (Float) y, shutterOpen);
++numRays;
if (!m_kdtree->rayIntersect(primary, its)) {
@ -88,7 +89,7 @@ void PreviewWorker::processIncoherent(const WorkUnit *workUnit, WorkResult *work
value = Spectrum(0.0f);
toVPL = m_vpl.its.p - its.p;
secondary = Ray(its.p, toVPL, ShadowEpsilon, 1-ShadowEpsilon, 0.0f);
secondary = Ray(its.p, toVPL, ShadowEpsilon, 1-ShadowEpsilon, shutterOpen);
++numRays;
if (m_kdtree->rayIntersect(secondary)) {
block->setPixel(pos++, value);
@ -352,6 +353,7 @@ void PreviewWorker::processCoherent(const WorkUnit *workUnit, WorkResult *workRe
);
its.t = its4.t.f[idx];
shape->fillIntersectionRecord(ray, temp + idx * MTS_KD_INTERSECTION_TEMP + 8, its);
bsdf = its.shape->getBSDF();
}
wo.x = nSecD[0].f[idx]; wo.y = nSecD[1].f[idx]; wo.z = nSecD[2].f[idx];

View File

@ -18,7 +18,7 @@
#include <mitsuba/core/platform.h>
#include <xercesc/parsers/SAXParser.hpp>
#include <mitsuba/render/shandler.h>
#include <mitsuba/render/scenehandler.h>
#include <mitsuba/core/fresolver.h>
#include <boost/algorithm/string.hpp>

View File

@ -20,7 +20,7 @@
#include <xercesc/parsers/SAXParser.hpp>
#include <mitsuba/core/fresolver.h>
#include <mitsuba/render/util.h>
#include <mitsuba/render/shandler.h>
#include <mitsuba/render/scenehandler.h>
MTS_NAMESPACE_BEGIN

View File

@ -26,7 +26,7 @@
#include <mitsuba/core/shvector.h>
#include <mitsuba/core/statistics.h>
#include <mitsuba/render/renderjob.h>
#include <mitsuba/render/shandler.h>
#include <mitsuba/render/scenehandler.h>
#include <fstream>
#include <stdexcept>

View File

@ -27,7 +27,7 @@
#include <mitsuba/core/appender.h>
#include <mitsuba/render/util.h>
#include <mitsuba/render/renderjob.h>
#include <mitsuba/render/shandler.h>
#include <mitsuba/render/scenehandler.h>
#include <boost/algorithm/string.hpp>
#include <fstream>
#include <stdexcept>

View File

@ -19,7 +19,7 @@
#include <xercesc/parsers/SAXParser.hpp>
#include "glwidget.h"
#include "sceneloader.h"
#include <mitsuba/render/shandler.h>
#include <mitsuba/render/scenehandler.h>
#include <mitsuba/core/fresolver.h>
#include <mitsuba/core/fstream.h>
#include <boost/algorithm/string.hpp>

View File

@ -39,6 +39,7 @@ public:
: Shape(stream, manager) {
m_shapeGroup = static_cast<ShapeGroup *>(manager->getInstance(stream));
m_transform = new AnimatedTransform(stream);
configure();
}
void serialize(Stream *stream, InstanceManager *manager) const {
@ -134,5 +135,5 @@ private:
};
MTS_IMPLEMENT_CLASS_S(AnimatedInstance, false, Shape)
MTS_EXPORT_PLUGIN(AnimatedInstance, "AnimatedInstanced geometry");
MTS_EXPORT_PLUGIN(AnimatedInstance, "Animated instanced geometry");
MTS_NAMESPACE_END

View File

@ -46,7 +46,8 @@ public:
}
inline Spectrum getValue(const Point2 &uv) const {
int x = 2*(((int) (uv.x * 2)) % 2) - 1, y = 2*(((int) (uv.y * 2)) % 2) - 1;
int x = 2*modulo((int) (uv.x * 2), 2) - 1,
y = 2*modulo((int) (uv.y * 2), 2) - 1;
if (x*y == 1)
return m_brightColor;

View File

@ -215,6 +215,17 @@ class MtsAdjustments:
self.out.write('\t\t</shape>\n')
self.out.write('\n')
def exportCameraSettings(self, scene, camera):
if scene.mitsuba_integrator.motionblur:
frameTime = 1.0/scene.render.fps
shuttertime = scene.mitsuba_integrator.shuttertime
shutterOpen = (scene.frame_current - shuttertime/2) * frameTime
shutterClose = (scene.frame_current + shuttertime/2) * frameTime
self.out.write('\t<prepend id="%s-camera">\n' % translate_id(camera.name))
self.out.write('\t\t<float name="shutterOpen" value="%f"/>\n' % shutterOpen)
self.out.write('\t\t<float name="shutterClose" value="%f"/>\n' % shutterClose)
self.out.write('\t</prepend>\n')
def export(self, scene):
idx = 0
self.writeHeader()
@ -228,6 +239,8 @@ class MtsAdjustments:
self.exportMaterial(mat)
if len(obj.data.materials) > 0 and obj.data.materials[0].mitsuba_emission.use_emission:
self.exportEmission(obj)
elif obj.type == 'CAMERA':
self.exportCameraSettings(scene, obj)
idx = idx+1
self.writeFooter()

View File

@ -184,9 +184,11 @@ class EXPORT_OT_mitsuba(bpy.types.Operator):
MtsLog("MtsBlend: Launching mtsimport")
try:
process = subprocess.Popen(
[mtsimport_binary, '-r', '%dx%d' % (width, height),
'-l', 'pngfilm', mts_dae_file, mts_xml_file, mts_adj_file],
command = [mtsimport_binary, '-r', '%dx%d' % (width, height),
'-n', '-l', 'pngfilm', mts_dae_file, mts_xml_file, mts_adj_file]
if scene.mitsuba_integrator.motionblur:
command += ['-z']
process = subprocess.Popen(command,
env = env,
cwd = mts_path
)

View File

@ -28,7 +28,6 @@ class MtsFilmDisplay(TimerThread):
result = self.LocalStorage['RE'].begin_result(0, 0, int(xres), int(yres))
if os.path.exists(self.LocalStorage['output_file']):
bpy.ops.ef.msg(msg_text='Updating RenderResult')
lay = result.layers[0]
lay.load_from_file(self.LocalStorage['output_file'])
else:

View File

@ -28,9 +28,14 @@ class mitsuba_integrator(declarative_property_group):
controls = [
'type',
'sampleCount'
['motionblur',
'shuttertime']
]
visibility = {
'shuttertime': { 'motionblur': True }
}
properties = [
{
'type': 'enum',
@ -43,6 +48,24 @@ class mitsuba_integrator(declarative_property_group):
('path', 'Path tracer', 'path'),
],
'save_in_preset': True
},
{
'type': 'bool',
'attr': 'motionblur',
'name': 'Motion Blur',
'description': 'Should motion blur be enabled?',
'default' : False,
'save_in_preset': True
},
{
'type': 'float',
'attr': 'shuttertime',
'name': 'Shutter time',
'description': 'Amount of time, for which the shutter remains open (measured in frames)',
'save_in_preset': True,
'min': 0,
'max': 100,
'default': 1
}
]

View File

@ -16,7 +16,7 @@
#
# ##### END GPL LICENSE BLOCK #####
import bpy, copy
import bpy
from properties_material import MaterialButtonsPanel
from extensions_framework.ui import property_group_renderer
@ -27,13 +27,20 @@ material_cache = {}
cached_spp = None
cached_depth = None
def copy(value):
if value == None or isinstance(value, str) or isinstance(value, bool) \
or isinstance(value, float) or isinstance(value, int):
return value
elif getattr(value, '__len__', False):
return list(value)
else:
raise Exception("Copy: don't know how to handle '%s'" % str(vlaue))
class mitsuba_material_base(MaterialButtonsPanel, property_group_renderer):
COMPAT_ENGINES = {'mitsuba'}
MTS_PROPS = ['type']
def draw(self, context):
if not hasattr(context, 'material'):
return
def validate(self, context):
global material_cache
mat = context.material
if mat.name in material_cache:
@ -45,15 +52,20 @@ class mitsuba_material_base(MaterialButtonsPanel, property_group_renderer):
mat = self.get_contents(mat)
repaint = False
for prop in self.MTS_PROPS:
prop_value = getattr(mat, prop)
prop_value = copy(getattr(mat, prop))
prop_cache_value = mat_cached[prop] if prop in mat_cached else None
if prop_cache_value != prop_value:
mat_cached[prop] = copy.copy(prop_value)
mat_cached[prop] = prop_value
repaint = True
if repaint:
# Cause a repaint
MtsLog("Forcing a repaint")
context.material.preview_render_type = context.material.preview_render_type
def draw(self, context):
if not hasattr(context, 'material'):
return
self.validate(context)
return super().draw(context)
def get_contents(self, mat):
@ -93,10 +105,10 @@ class mitsuba_material_sub(MaterialButtonsPanel, property_group_renderer):
repaint = False
for prop_entry in props:
prop = prop_entry['attr']
prop_value = getattr(mat, prop) if hasattr(mat, prop) else None
prop_value = copy(getattr(mat, prop) if hasattr(mat, prop) else None)
prop_cache_value = mat_cached[prop] if prop in mat_cached else None
if prop_cache_value != prop_value:
mat_cached[prop] = copy.copy(prop_value)
if prop_cache_value != copy(prop_value):
mat_cached[prop] = prop_value
repaint = True
if repaint:
# Cause a repaint

View File

@ -41,3 +41,4 @@ class emission(mitsuba_material_base, bpy.types.Panel):
if hasattr(context, "material"):
mat = active_node_mat(context.material)
self.layout.prop(mat.mitsuba_emission, "use_emission", text="")
self.validate(context)

BIN
tools/windows/mitsuba.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB