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/preview.cpp', 'src/librender/photonmap.cpp',
'src/librender/gatherproc.cpp', 'src/librender/mipmap3d.cpp', 'src/librender/gatherproc.cpp', 'src/librender/mipmap3d.cpp',
'src/librender/volume.cpp', 'src/librender/vpl.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' '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 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. 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} \subsection{Property types}
This section documents all of the ways in which properties can be supplied to objects. If you are more 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. 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:complexType>
<xsd:choice minOccurs="0" maxOccurs="unbounded"> <xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="camera" type="camera"/> <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="bsdf" type="bsdf"/>
<xsd:element name="integrator" type="integrator"/> <xsd:element name="integrator" type="integrator"/>
<xsd:element name="luminaire" type="luminaire"/> <xsd:element name="luminaire" type="luminaire"/>
@ -29,9 +29,9 @@
</xsd:element> </xsd:element>
<!-- Generic Object --> <!-- Generic Object -->
<xsd:complexType name="object"> <xsd:group name="objectGroup">
<xsd:choice minOccurs="0" maxOccurs="unbounded"> <!-- Allow all property types -->
<!-- Usual attributes --> <xsd:choice>
<xsd:element name="integer" type="integer"/> <xsd:element name="integer" type="integer"/>
<xsd:element name="float" type="float"/> <xsd:element name="float" type="float"/>
<xsd:element name="point" type="point"/> <xsd:element name="point" type="point"/>
@ -44,12 +44,27 @@
<xsd:element name="srgb" type="string"/> <xsd:element name="srgb" type="string"/>
<xsd:element name="blackbody" type="blackbody"/> <xsd:element name="blackbody" type="blackbody"/>
</xsd:choice> </xsd:choice>
</xsd:group>
<xsd:complexType name="objectBase">
<xsd:attribute name="type" type="xsd:string" use="required"/> <xsd:attribute name="type" type="xsd:string" use="required"/>
<xsd:attribute name="name" type="xsd:string"/> <xsd:attribute name="name" type="xsd:string"/>
<xsd:attribute name="id" type="xsd:string"/> <xsd:attribute name="id" type="xsd:string"/>
</xsd:complexType> </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:complexType name="reference">
<xsd:attribute name="id" type="xsd:string" use="required"/> <xsd:attribute name="id" type="xsd:string" use="required"/>
<xsd:attribute name="name" type="xsd:string"/> <xsd:attribute name="name" type="xsd:string"/>
@ -58,8 +73,9 @@
<!-- CAMERA Element --> <!-- CAMERA Element -->
<xsd:complexType name="camera"> <xsd:complexType name="camera">
<xsd:complexContent> <xsd:complexContent>
<xsd:extension base="object"> <xsd:extension base="objectBase">
<xsd:choice minOccurs="0" maxOccurs="unbounded"> <xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:group ref="objectGroup"/>
<xsd:element name="sampler" type="object"/> <xsd:element name="sampler" type="object"/>
<xsd:element name="film" type="film"/> <xsd:element name="film" type="film"/>
</xsd:choice> </xsd:choice>
@ -70,21 +86,23 @@
<!-- INTEGRATOR Element --> <!-- INTEGRATOR Element -->
<xsd:complexType name="integrator"> <xsd:complexType name="integrator">
<xsd:complexContent> <xsd:complexContent>
<xsd:extension base="object"> <xsd:extension base="objectBase">
<xsd:choice minOccurs="0" maxOccurs="unbounded"> <xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:group ref="objectGroup"/>
<xsd:element name="integrator" type="integrator"/> <xsd:element name="integrator" type="integrator"/>
<xsd:element name="sampler" type="object"/> <xsd:element name="sampler" type="object"/>
</xsd:choice> </xsd:choice>
</xsd:extension> </xsd:extension>
</xsd:complexContent> </xsd:complexContent>
</xsd:complexType> </xsd:complexType>
<!-- LUMINAIRE Element --> <!-- LUMINAIRE Element -->
<xsd:complexType name="luminaire"> <xsd:complexType name="luminaire">
<xsd:complexContent> <xsd:complexContent>
<xsd:extension base="object"> <xsd:extension base="objectBase">
<xsd:choice minOccurs="0" maxOccurs="unbounded"> <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:element name="luminaire" type="luminaire"/>
</xsd:choice> </xsd:choice>
</xsd:extension> </xsd:extension>
@ -95,8 +113,9 @@
<!-- SHAPE Element --> <!-- SHAPE Element -->
<xsd:complexType name="shape"> <xsd:complexType name="shape">
<xsd:complexContent> <xsd:complexContent>
<xsd:extension base="object"> <xsd:extension base="objectBase">
<xsd:choice minOccurs="0" maxOccurs="unbounded"> <xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:group ref="objectGroup"/>
<xsd:element name="bsdf" type="bsdf"/> <xsd:element name="bsdf" type="bsdf"/>
<xsd:element name="subsurface" type="object"/> <xsd:element name="subsurface" type="object"/>
<xsd:element name="ref" type="reference"/> <xsd:element name="ref" type="reference"/>
@ -110,12 +129,12 @@
<!-- VOLUMEREGION Element --> <!-- VOLUMEREGION Element -->
<xsd:complexType name="medium"> <xsd:complexType name="medium">
<xsd:complexContent> <xsd:complexContent>
<xsd:extension base="object"> <xsd:extension base="objectBase">
<xsd:choice minOccurs="0" maxOccurs="unbounded"> <xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:group ref="objectGroup"/>
<xsd:element name="shape" type="shape"/> <xsd:element name="shape" type="shape"/>
<xsd:element name="volume" type="object"/> <xsd:element name="volume" type="object"/>
<xsd:element name="phase" type="phase"/> <xsd:element name="phase" type="phase"/>
<xsd:element name="ref" type="reference"/>
</xsd:choice> </xsd:choice>
</xsd:extension> </xsd:extension>
</xsd:complexContent> </xsd:complexContent>
@ -124,9 +143,10 @@
<!-- BSDF Element --> <!-- BSDF Element -->
<xsd:complexType name="bsdf"> <xsd:complexType name="bsdf">
<xsd:complexContent> <xsd:complexContent>
<xsd:extension base="object"> <xsd:extension base="objectBase">
<xsd:choice minOccurs="0" maxOccurs="unbounded"> <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="bsdf" type="bsdf"/>
<xsd:element name="ref" type="reference"/> <xsd:element name="ref" type="reference"/>
</xsd:choice> </xsd:choice>
@ -134,24 +154,41 @@
</xsd:complexContent> </xsd:complexContent>
</xsd:complexType> </xsd:complexType>
<!-- Phase Element --> <!-- TEXTURE Element -->
<xsd:complexType name="phase"> <xsd:complexType name="texture">
<xsd:complexContent> <xsd:complexContent>
<xsd:extension base="object"/> <xsd:extension base="objectBase">
</xsd:complexContent>
</xsd:complexType>
<!-- Film Element -->
<xsd:complexType name="film">
<xsd:complexContent>
<xsd:extension base="object">
<xsd:choice minOccurs="0" maxOccurs="unbounded"> <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:choice>
</xsd:extension> </xsd:extension>
</xsd:complexContent> </xsd:complexContent>
</xsd:complexType> </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 --> <!-- Types and parameters -->
<xsd:simpleType name="integerType"> <xsd:simpleType name="integerType">
@ -196,15 +233,16 @@
</xsd:union> </xsd:union>
</xsd:simpleType> </xsd:simpleType>
<xsd:complexType name="float"> <xsd:complexType name="float">
<xsd:attribute name="name" type="xsd:string" use="required"/> <xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="value" type="doubleType" use="required"/> <xsd:attribute name="value" type="doubleType" use="required"/>
</xsd:complexType> </xsd:complexType>
<xsd:complexType name="integer"> <xsd:complexType name="integer">
<xsd:attribute name="name" type="xsd:string" use="required"/> <xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="value" type="integerType" use="required"/> <xsd:attribute name="value" type="integerType" use="required"/>
</xsd:complexType> </xsd:complexType>
<xsd:complexType name="boolean"> <xsd:complexType name="boolean">
<xsd:attribute name="name" type="xsd:string" use="required"/> <xsd:attribute name="name" type="xsd:string" use="required"/>
<xsd:attribute name="value" type="booleanType" 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; ctx.os << "\t<camera id=\"" << identifier << "\" type=\"perspective\">" << endl;
if (persp->getXfov().cast()) { if (persp->getXfov().cast()) {
Float xFov = (Float) persp->getXfov()->getValue(); 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)); 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) if (aspect <= 1.0f)
ctx.os << "\t\t<float name=\"fov\" value=\"" << xFov << "\"/>" << endl; ctx.os << "\t\t<float name=\"fov\" value=\"" << xFov << "\"/>" << endl;
else else
ctx.os << "\t\t<float name=\"fov\" value=\"" << yFov << "\"/>" << endl; ctx.os << "\t\t<float name=\"fov\" value=\"" << yFov << "\"/>" << endl;
} else if (persp->getYfov().cast()) { } else if (persp->getYfov().cast()) {
Float yFov = (Float) persp->getYfov()->getValue(); 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)); 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) if (aspect > 1.0f)
ctx.os << "\t\t<float name=\"fov\" value=\"" << yFov << "\"/>" << endl; ctx.os << "\t\t<float name=\"fov\" value=\"" << yFov << "\"/>" << endl;
else 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\t<matrix value=\"" << matrixValues.substr(0, matrixValues.length()-1) << "\"/>" << endl;
ctx.os << "\t\t</transform>" << endl << endl; ctx.os << "\t\t</transform>" << endl << endl;
ctx.os << "\t\t<sampler id=\"sampler\" type=\"ldsampler\">" << 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</sampler>" << endl << endl;
ctx.os << "\t\t<film id=\"film\" type=\"" << ctx.cvt->m_filmType << "\">" << 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; ctx.os << "\t\t\t<integer name=\"width\" value=\"" << xres << "\"/>" << endl;
@ -1619,34 +1605,38 @@ void GeometryConverter::convertCollada(const fs::path &inputFile,
ctx.cvt = this; ctx.cvt = this;
ctx.trackIndex = 0; ctx.trackIndex = 0;
domLibrary_images_Array &libraryImages = document->getLibrary_images_array(); if (m_importMaterials) {
for (size_t i=0; i<libraryImages.getCount(); ++i) { domLibrary_images_Array &libraryImages = document->getLibrary_images_array();
domImage_Array &images = libraryImages[i]->getImage_array(); for (size_t i=0; i<libraryImages.getCount(); ++i) {
for (size_t j=0; j<images.getCount(); ++j) domImage_Array &images = libraryImages[i]->getImage_array();
loadImage(ctx, *images.get(j)); for (size_t j=0; j<images.getCount(); ++j)
} loadImage(ctx, *images.get(j));
}
domLibrary_materials_Array &libraryMaterials = document->getLibrary_materials_array(); domLibrary_materials_Array &libraryMaterials = document->getLibrary_materials_array();
for (size_t i=0; i<libraryMaterials.getCount(); ++i) { for (size_t i=0; i<libraryMaterials.getCount(); ++i) {
domMaterial_Array &materials = libraryMaterials[i]->getMaterial_array(); domMaterial_Array &materials = libraryMaterials[i]->getMaterial_array();
for (size_t j=0; j<materials.getCount(); ++j) for (size_t j=0; j<materials.getCount(); ++j)
loadMaterial(ctx, *materials.get(j)); loadMaterial(ctx, *materials.get(j));
}
} }
domLibrary_animations_Array &libraryAnimations = document->getLibrary_animations_array(); if (m_importAnimations) {
for (size_t i=0; i<libraryAnimations.getCount(); ++i) { domLibrary_animations_Array &libraryAnimations = document->getLibrary_animations_array();
domAnimation_Array &animations = libraryAnimations[i]->getAnimation_array(); for (size_t i=0; i<libraryAnimations.getCount(); ++i) {
for (size_t j=0; j<animations.getCount(); ++j) domAnimation_Array &animations = libraryAnimations[i]->getAnimation_array();
loadAnimation(ctx, *animations[j]); for (size_t j=0; j<animations.getCount(); ++j)
loadAnimation(ctx, *animations[j]);
}
mergeRotations(ctx);
} }
mergeRotations(ctx);
for (size_t i=0; i<nodes.getCount(); ++i) for (size_t i=0; i<nodes.getCount(); ++i)
computeRefCounts(ctx, *nodes[i]); computeRefCounts(ctx, *nodes[i]);
for (size_t i=0; i<nodes.getCount(); ++i) for (size_t i=0; i<nodes.getCount(); ++i)
loadNode(ctx, Transform(), *nodes[i], ""); loadNode(ctx, Transform(), *nodes[i], "");
for (AnimationMap::iterator it = ctx.animations.begin(); for (AnimationMap::iterator it = ctx.animations.begin();
it != ctx.animations.end(); ++it) it != ctx.animations.end(); ++it)
it->second->decRef(); it->second->decRef();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -68,13 +68,14 @@ void PreviewWorker::processIncoherent(const WorkUnit *workUnit, WorkResult *work
Vector toVPL; Vector toVPL;
Ray primary, secondary; Ray primary, secondary;
int numRays = 0; int numRays = 0;
float shutterOpen = m_scene->getCamera()->getShutterOpen();
for (int y=sy; y<ey; ++y) { for (int y=sy; y<ey; ++y) {
for (int x=sx; x<ex; ++x) { for (int x=sx; x<ex; ++x) {
/* Generate a camera ray without normalization */ /* Generate a camera ray without normalization */
primary = Ray(m_cameraO, m_cameraTL primary = Ray(m_cameraO, m_cameraTL
+ m_cameraDx * (Float) x + m_cameraDx * (Float) x
+ m_cameraDy * (Float) y, 0.0f); + m_cameraDy * (Float) y, shutterOpen);
++numRays; ++numRays;
if (!m_kdtree->rayIntersect(primary, its)) { if (!m_kdtree->rayIntersect(primary, its)) {
@ -88,7 +89,7 @@ void PreviewWorker::processIncoherent(const WorkUnit *workUnit, WorkResult *work
value = Spectrum(0.0f); value = Spectrum(0.0f);
toVPL = m_vpl.its.p - its.p; 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; ++numRays;
if (m_kdtree->rayIntersect(secondary)) { if (m_kdtree->rayIntersect(secondary)) {
block->setPixel(pos++, value); block->setPixel(pos++, value);
@ -352,6 +353,7 @@ void PreviewWorker::processCoherent(const WorkUnit *workUnit, WorkResult *workRe
); );
its.t = its4.t.f[idx]; its.t = its4.t.f[idx];
shape->fillIntersectionRecord(ray, temp + idx * MTS_KD_INTERSECTION_TEMP + 8, its); 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]; 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 <mitsuba/core/platform.h>
#include <xercesc/parsers/SAXParser.hpp> #include <xercesc/parsers/SAXParser.hpp>
#include <mitsuba/render/shandler.h> #include <mitsuba/render/scenehandler.h>
#include <mitsuba/core/fresolver.h> #include <mitsuba/core/fresolver.h>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -46,7 +46,8 @@ public:
} }
inline Spectrum getValue(const Point2 &uv) const { 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) if (x*y == 1)
return m_brightColor; return m_brightColor;

View File

@ -215,6 +215,17 @@ class MtsAdjustments:
self.out.write('\t\t</shape>\n') self.out.write('\t\t</shape>\n')
self.out.write('\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): def export(self, scene):
idx = 0 idx = 0
self.writeHeader() self.writeHeader()
@ -228,6 +239,8 @@ class MtsAdjustments:
self.exportMaterial(mat) self.exportMaterial(mat)
if len(obj.data.materials) > 0 and obj.data.materials[0].mitsuba_emission.use_emission: if len(obj.data.materials) > 0 and obj.data.materials[0].mitsuba_emission.use_emission:
self.exportEmission(obj) self.exportEmission(obj)
elif obj.type == 'CAMERA':
self.exportCameraSettings(scene, obj)
idx = idx+1 idx = idx+1
self.writeFooter() self.writeFooter()

View File

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

View File

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

View File

@ -28,8 +28,13 @@ class mitsuba_integrator(declarative_property_group):
controls = [ controls = [
'type', 'type',
'sampleCount' ['motionblur',
'shuttertime']
] ]
visibility = {
'shuttertime': { 'motionblur': True }
}
properties = [ properties = [
{ {
@ -43,6 +48,24 @@ class mitsuba_integrator(declarative_property_group):
('path', 'Path tracer', 'path'), ('path', 'Path tracer', 'path'),
], ],
'save_in_preset': True '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 ##### # ##### END GPL LICENSE BLOCK #####
import bpy, copy import bpy
from properties_material import MaterialButtonsPanel from properties_material import MaterialButtonsPanel
from extensions_framework.ui import property_group_renderer from extensions_framework.ui import property_group_renderer
@ -27,13 +27,20 @@ material_cache = {}
cached_spp = None cached_spp = None
cached_depth = 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): class mitsuba_material_base(MaterialButtonsPanel, property_group_renderer):
COMPAT_ENGINES = {'mitsuba'} COMPAT_ENGINES = {'mitsuba'}
MTS_PROPS = ['type'] MTS_PROPS = ['type']
def draw(self, context): def validate(self, context):
if not hasattr(context, 'material'):
return
global material_cache global material_cache
mat = context.material mat = context.material
if mat.name in material_cache: if mat.name in material_cache:
@ -45,15 +52,20 @@ class mitsuba_material_base(MaterialButtonsPanel, property_group_renderer):
mat = self.get_contents(mat) mat = self.get_contents(mat)
repaint = False repaint = False
for prop in self.MTS_PROPS: 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 prop_cache_value = mat_cached[prop] if prop in mat_cached else None
if prop_cache_value != prop_value: if prop_cache_value != prop_value:
mat_cached[prop] = copy.copy(prop_value) mat_cached[prop] = prop_value
repaint = True repaint = True
if repaint: if repaint:
# Cause a repaint # Cause a repaint
MtsLog("Forcing a repaint") MtsLog("Forcing a repaint")
context.material.preview_render_type = context.material.preview_render_type 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) return super().draw(context)
def get_contents(self, mat): def get_contents(self, mat):
@ -93,10 +105,10 @@ class mitsuba_material_sub(MaterialButtonsPanel, property_group_renderer):
repaint = False repaint = False
for prop_entry in props: for prop_entry in props:
prop = prop_entry['attr'] 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 prop_cache_value = mat_cached[prop] if prop in mat_cached else None
if prop_cache_value != prop_value: if prop_cache_value != copy(prop_value):
mat_cached[prop] = copy.copy(prop_value) mat_cached[prop] = prop_value
repaint = True repaint = True
if repaint: if repaint:
# Cause a repaint # Cause a repaint

View File

@ -41,3 +41,4 @@ class emission(mitsuba_material_base, bpy.types.Panel):
if hasattr(context, "material"): if hasattr(context, "material"):
mat = active_node_mat(context.material) mat = active_node_mat(context.material)
self.layout.prop(mat.mitsuba_emission, "use_emission", text="") 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