bug-huting

metadata
Wenzel Jakob 2011-04-06 02:07:04 +02:00
parent d5890fc4d0
commit 4bf47e36b2
19 changed files with 150 additions and 72 deletions

View File

@ -311,7 +311,7 @@ class MtsExporter:
self.parameter('float', 'samplingWeight', {'value' : '%f' % lamp.data.mitsuba_lamp.samplingWeight}) self.parameter('float', 'samplingWeight', {'value' : '%f' % lamp.data.mitsuba_lamp.samplingWeight})
if lamp.data.mitsuba_lamp.inside_medium: if lamp.data.mitsuba_lamp.inside_medium:
self.exportMediumReference(scene, lamp, nil, lamp.data.mitsuba_lamp.lamp_medium) self.exportMediumReference(scene, lamp, None, lamp.data.mitsuba_lamp.lamp_medium)
self.closeElement() self.closeElement()
elif ltype == 'AREA': elif ltype == 'AREA':
self.element('remove', { 'id' : '%s-light' % name}) self.element('remove', { 'id' : '%s-light' % name})
@ -559,7 +559,7 @@ class MtsExporter:
self.exportSampler(scene.mitsuba_sampler) self.exportSampler(scene.mitsuba_sampler)
for obj in scene.objects: for obj in scene.objects:
if obj.type == 'LAMP': if obj.type == 'LAMP':
self.exportLamp(obj, idx) self.exportLamp(scene, obj, idx)
elif obj.type == 'MESH': elif obj.type == 'MESH':
for mat in obj.data.materials: for mat in obj.data.materials:
self.exportMaterial(mat) self.exportMaterial(mat)

View File

@ -42,6 +42,48 @@ def dict_merge(*args):
vis.update(deepcopy(vis_dict)) vis.update(deepcopy(vis_dict))
return vis return vis
mat_names = {
'lambertian' : 'Lambertian',
'phong' : 'Phong',
'ward' : 'Anisotropic Ward',
'mirror' : 'Ideal mirror',
'dielectric' : 'Ideal dielectric',
'roughmetal' : 'Rough metal',
'roughglass' : 'Rough glass',
'microfacet' : 'Microfacet',
'composite' : 'Composite material',
'difftrans' : 'Diffuse transmitter',
'none' : 'Passthrough material'
}
@MitsubaAddon.addon_register_class
class MATERIAL_OT_set_mitsuba_type(bpy.types.Operator):
bl_idname = 'material.set_mitsuba_type'
bl_label = 'Set material type'
mat_name = bpy.props.StringProperty()
@classmethod
def poll(cls, context):
return context.material and \
context.material.mitsuba_material
def execute(self, context):
context.material.mitsuba_material.set_type(self.properties.mat_name)
return {'FINISHED'}
@MitsubaAddon.addon_register_class
class MATERIAL_MT_mitsuba_type(bpy.types.Menu):
bl_label = 'Material Type'
def draw(self, context):
sl = self.layout
from operator import itemgetter
result = sorted(mat_names.items(), key=itemgetter(1))
for item in result:
print(result)
op = sl.operator('MATERIAL_OT_set_mitsuba_type', text = item[1])
op.mat_name = item[0]
@MitsubaAddon.addon_register_class @MitsubaAddon.addon_register_class
class mitsuba_material(declarative_property_group): class mitsuba_material(declarative_property_group):
@ -54,7 +96,6 @@ class mitsuba_material(declarative_property_group):
ef_attach_to = ['Material'] ef_attach_to = ['Material']
controls = [ controls = [
'type',
'twosided', 'twosided',
'is_medium_transition', 'is_medium_transition',
'interior', 'interior',
@ -62,7 +103,8 @@ class mitsuba_material(declarative_property_group):
] ]
visibility = { visibility = {
'twosided' : { 'type' : O(['lambertian', 'phong', 'ward', 'mirror', 'roughmetal', 'microfacet', 'composite'])}, 'twosided' : { 'type' : O(['lambertian', 'phong', 'ward',
'mirror', 'roughmetal', 'microfacet', 'composite'])},
'exterior' : { 'is_medium_transition' : True }, 'exterior' : { 'is_medium_transition' : True },
'interior' : { 'is_medium_transition' : True } 'interior' : { 'is_medium_transition' : True }
} }
@ -70,24 +112,17 @@ class mitsuba_material(declarative_property_group):
properties = [ properties = [
# Material Type Select # Material Type Select
{ {
'type': 'enum', 'attr': 'type_label',
'name': 'Mitsuba material type',
'type': 'string',
'default': 'Lambertian',
'save_in_preset': True
},
{
'type': 'string',
'attr': 'type', 'attr': 'type',
'name': 'Material Type', 'name': 'Type',
'description': 'Mitsuba material type',
'default': 'lambertian', 'default': 'lambertian',
'items': [
('none', 'None (passthrough)', 'Passthrough material. This is useful for creating participating media with index-matched boundaries'),
('difftrans', 'Diffuse transmitter', 'Material with an ideally diffuse transmittance'),
('microfacet', 'Microfacet', 'Microfacet material (like the rough glass material, but without transmittance)'),
('composite', 'Composite material', 'Allows creating mixtures of different materials'),
('roughglass', 'Rough glass', 'Rough dielectric material (e.g. sand-blasted glass)'),
('roughmetal', 'Rough metal', 'Rough conductor (e.g. sand-blasted metal)'),
('dielectric', 'Ideal dielectric', 'Ideal dielectric material (e.g. glass)'),
('mirror', 'Ideal mirror', 'Ideal mirror material'),
('ward', 'Anisotropic Ward', 'Anisotropic Ward BRDF'),
('phong', 'Phong', 'Modified Phong BRDF'),
('lambertian', 'Lambertian', 'Lambertian (i.e. ideally diffuse) material')
],
'save_in_preset': True 'save_in_preset': True
}, },
{ {
@ -109,6 +144,9 @@ class mitsuba_material(declarative_property_group):
] + MediumParameter('interior', 'Interior') \ ] + MediumParameter('interior', 'Interior') \
+ MediumParameter('exterior', 'Exterior') + MediumParameter('exterior', 'Exterior')
def set_type(self, mat_type):
self.type = mat_type
self.type_label = mat_names[mat_type]
def get_params(self): def get_params(self):
sub_type = getattr(self, 'mitsuba_mat_%s' % self.type) sub_type = getattr(self, 'mitsuba_mat_%s' % self.type)

View File

@ -42,5 +42,7 @@ class main(mitsuba_material_base, bpy.types.Panel):
row.operator("mitsuba.convert_all_materials", icon='WORLD_DATA') row.operator("mitsuba.convert_all_materials", icon='WORLD_DATA')
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.operator("mitsuba.convert_material", icon='MATERIAL_DATA') row.operator("mitsuba.convert_material", icon='MATERIAL_DATA')
row = self.layout.row(align=True)
row.menu('MATERIAL_MT_mitsuba_type', text=context.material.mitsuba_material.type_label)
super().draw(context) super().draw(context)

View File

@ -54,6 +54,9 @@ inline Spectrum Intersection::LoSub(const Scene *scene, const Vector &d) const {
inline const BSDF *Intersection::getBSDF(const RayDifferential &ray) { inline const BSDF *Intersection::getBSDF(const RayDifferential &ray) {
const BSDF *bsdf = shape->getBSDF(); const BSDF *bsdf = shape->getBSDF();
if (bsdf)
cout << "getBSDF(): " << bsdf->usesRayDifferentials() << ", hasUVPartials=" << hasUVPartials << endl;
if (bsdf && bsdf->usesRayDifferentials() && !hasUVPartials) if (bsdf && bsdf->usesRayDifferentials() && !hasUVPartials)
computePartials(ray); computePartials(ray);
return bsdf; return bsdf;

View File

@ -26,6 +26,10 @@
#include <stack> #include <stack>
#include <map> #include <map>
XERCES_CPP_NAMESPACE_BEGIN
class SAXParser;
XERCES_CPP_NAMESPACE_END
XERCES_CPP_NAMESPACE_USE XERCES_CPP_NAMESPACE_USE
MTS_NAMESPACE_BEGIN MTS_NAMESPACE_BEGIN
@ -37,8 +41,8 @@ public:
typedef std::map<std::string, ConfigurableObject *> NamedObjectMap; typedef std::map<std::string, ConfigurableObject *> NamedObjectMap;
typedef std::map<std::string, std::string> ParameterMap; typedef std::map<std::string, std::string> ParameterMap;
SceneHandler(const ParameterMap &params, NamedObjectMap *objects = NULL, SceneHandler(const SAXParser *parser, const ParameterMap &params,
bool isIncludedFile = false); NamedObjectMap *objects = NULL, bool isIncludedFile = false);
virtual ~SceneHandler(); virtual ~SceneHandler();
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@ -69,6 +73,8 @@ protected:
XMLString::release(&value); XMLString::release(&value);
return result; return result;
} }
Float parseFloat(const std::string &name, const std::string &str,
Float defVal = -1) const;
void clear(); void clear();
@ -84,6 +90,7 @@ private:
std::vector<std::pair<std::string, ConfigurableObject *> > children; std::vector<std::pair<std::string, ConfigurableObject *> > children;
}; };
const SAXParser *m_parser;
ref<Scene> m_scene; ref<Scene> m_scene;
ParameterMap m_params; ParameterMap m_params;
NamedObjectMap *m_namedObjects; NamedObjectMap *m_namedObjects;

View File

@ -248,8 +248,8 @@ public:
* No details about the intersection are returned, hence the * No details about the intersection are returned, hence the
* function is only useful for visibility queries. For most * function is only useful for visibility queries. For most
* shapes, this will simply call forward the call to \ref * shapes, this will simply call forward the call to \ref
* rayIntersect. When the shape actually contains a nested kd-tree, * rayIntersect. When the shape actually contains a nested
* some optimizations are possible. * kd-tree, some optimizations are possible.
*/ */
virtual bool rayIntersect(const Ray &ray, Float mint, Float maxt) const; virtual bool rayIntersect(const Ray &ray, Float mint, Float maxt) const;
@ -316,7 +316,7 @@ public:
// ============================================================= // =============================================================
/// Does the shape act as an occluder? /// Does the shape act as an occluder?
inline bool isOccluder() const { return m_bsdf.get() != NULL; } inline bool isOccluder() const { return m_occluder; }
/// Does the surface of this shape mark a medium transition? /// Does the surface of this shape mark a medium transition?
inline bool isMediumTransition() const { return m_interiorMedium.get() || m_exteriorMedium.get(); } inline bool isMediumTransition() const { return m_interiorMedium.get() || m_exteriorMedium.get(); }
/// Return the medium that lies on the interior of this shape (\c NULL == vacuum) /// Return the medium that lies on the interior of this shape (\c NULL == vacuum)
@ -351,7 +351,7 @@ public:
/// Return the shape's BSDF /// Return the shape's BSDF
inline BSDF *getBSDF() { return m_bsdf.get(); } inline BSDF *getBSDF() { return m_bsdf.get(); }
/// Set the BSDF of this shape /// Set the BSDF of this shape
inline void setBSDF(BSDF *bsdf) { m_bsdf = bsdf; } inline void setBSDF(BSDF *bsdf) { m_bsdf = bsdf; m_occluder = (bsdf != NULL); }
/// Called once after parsing /// Called once after parsing
virtual void configure(); virtual void configure();
@ -378,7 +378,9 @@ protected:
ref<BSDF> m_bsdf; ref<BSDF> m_bsdf;
ref<Subsurface> m_subsurface; ref<Subsurface> m_subsurface;
ref<Luminaire> m_luminaire; ref<Luminaire> m_luminaire;
ref<Medium> m_interiorMedium, m_exteriorMedium; ref<Medium> m_interiorMedium;
ref<Medium> m_exteriorMedium;
bool m_occluder;
}; };
inline ShapeSamplingRecord::ShapeSamplingRecord(const Intersection &its) inline ShapeSamplingRecord::ShapeSamplingRecord(const Intersection &its)

View File

@ -311,11 +311,9 @@ protected:
static_cast<const TriMesh *>(m_shapes[shapeIdx]); static_cast<const TriMesh *>(m_shapes[shapeIdx]);
const Triangle &tri = mesh->getTriangles()[idx]; const Triangle &tri = mesh->getTriangles()[idx];
Float tempU, tempV, tempT; Float tempU, tempV, tempT;
if (tri.rayIntersect(mesh->getVertexPositions(), ray, if (mesh->isOccluder() &&
tempU, tempV, tempT)) { tri.rayIntersect(mesh->getVertexPositions(), ray, tempU, tempV, tempT))
if (tempT >= mint && tempT <= maxt) return tempT >= mint && tempT <= maxt;
return mesh->isOccluder();
}
return false; return false;
} else { } else {
const Shape *shape = m_shapes[shapeIdx]; const Shape *shape = m_shapes[shapeIdx];

View File

@ -116,7 +116,9 @@ public:
std::string toString() const { std::string toString() const {
std::ostringstream oss; std::ostringstream oss;
oss << "Lambertian[reflectance=" << m_reflectance->toString() << "]"; oss << "Microfacet[" << endl
<< " reflectance = " << indent(m_reflectance->toString()) << endl
<< "]";
return oss.str(); return oss.str();
} }

View File

@ -69,6 +69,8 @@ public:
Spectrum Li(0.0f); Spectrum Li(0.0f);
Point2 sample; Point2 sample;
cout << "========================================================" << endl;
/* Perform the first ray intersection (or ignore if the /* Perform the first ray intersection (or ignore if the
intersection has already been provided). */ intersection has already been provided). */
if (!rRec.rayIntersect(ray)) { if (!rRec.rayIntersect(ray)) {
@ -89,6 +91,7 @@ public:
Li += its.LoSub(scene, -ray.d); Li += its.LoSub(scene, -ray.d);
const BSDF *bsdf = its.getBSDF(ray); const BSDF *bsdf = its.getBSDF(ray);
cout << its.toString() << endl;
if (EXPECT_NOT_TAKEN(!bsdf)) { if (EXPECT_NOT_TAKEN(!bsdf)) {
/* The direct illumination integrator doesn't support /* The direct illumination integrator doesn't support

View File

@ -71,6 +71,7 @@ void Intersection::computePartials(const RayDifferential &ray) {
} else { } else {
dudy = 0; dudy = 1; dudy = 0; dudy = 1;
} }
cout << "Computed " << dudx << "," << dudy << "," << dvdx << "," << dvdy << endl;
} }
std::string Intersection::toString() const { std::string Intersection::toString() const {
@ -83,7 +84,8 @@ std::string Intersection::toString() const {
<< " t = " << t << "," << std::endl << " t = " << t << "," << std::endl
<< " geoFrame = " << indent(geoFrame.toString()) << "," << std::endl << " geoFrame = " << indent(geoFrame.toString()) << "," << std::endl
<< " shFrame = " << indent(shFrame.toString()) << "," << std::endl << " shFrame = " << indent(shFrame.toString()) << "," << std::endl
<< " uv = " << uv.toString() << "," << std::endl; << " uv = " << uv.toString() << "," << std::endl
<< " hasUVPartials = " << hasUVPartials << "," << std::endl;
if (hasUVPartials) { if (hasUVPartials) {
oss << " dpdu = " << dpdu.toString() << "," << std::endl oss << " dpdu = " << dpdu.toString() << "," << std::endl
<< " dpdv = " << dpdv.toString() << "," << std::endl; << " dpdv = " << dpdv.toString() << "," << std::endl;

View File

@ -25,9 +25,14 @@
MTS_NAMESPACE_BEGIN MTS_NAMESPACE_BEGIN
SceneHandler::SceneHandler(const ParameterMap &params, NamedObjectMap *namedObjects, #define XMLLog(level, fmt, ...) Thread::getThread()->getLogger()->log(\
bool isIncludedFile) : m_params(params), m_namedObjects(namedObjects), level, NULL, __FILE__, __LINE__, "Near file offset %i: " fmt, \
m_isIncludedFile(isIncludedFile) { (int) m_parser->getSrcOffset(), ## __VA_ARGS__)
SceneHandler::SceneHandler(const SAXParser *parser,
const ParameterMap &params, NamedObjectMap *namedObjects,
bool isIncludedFile) : m_parser(parser), m_params(params),
m_namedObjects(namedObjects), m_isIncludedFile(isIncludedFile) {
m_pluginManager = PluginManager::getInstance(); m_pluginManager = PluginManager::getInstance();
if (m_isIncludedFile) { if (m_isIncludedFile) {
@ -73,16 +78,17 @@ void SceneHandler::characters(const XMLCh* const name,
const unsigned int length) { const unsigned int length) {
} }
static Float parseFloat(const std::string &name, const std::string &str, Float defVal = -1) { Float SceneHandler::parseFloat(const std::string &name,
const std::string &str, Float defVal) const {
char *end_ptr = NULL; char *end_ptr = NULL;
if (str == "") { if (str == "") {
if (defVal == -1) if (defVal == -1)
SLog(EError, "Missing floating point value (in <%s>)", name.c_str()); XMLLog(EError, "Missing floating point value (in <%s>)", name.c_str());
return defVal; return defVal;
} }
Float result = (Float) std::strtod(str.c_str(), &end_ptr); Float result = (Float) std::strtod(str.c_str(), &end_ptr);
if (*end_ptr != '\0') if (*end_ptr != '\0')
SLog(EError, "Invalid floating point value specified (in <%s>)", name.c_str()); XMLLog(EError, "Invalid floating point value specified (in <%s>)", name.c_str());
return result; return result;
} }
@ -106,7 +112,7 @@ void SceneHandler::startElement(const XMLCh* const xmlName,
} }
} }
if (attrValue.find('$') != attrValue.npos) if (attrValue.find('$') != attrValue.npos)
SLog(EError, "The scene referenced an undefined parameter: \"%s\"", attrValue.c_str()); XMLLog(EError, "The scene referenced an undefined parameter: \"%s\"", attrValue.c_str());
} }
context.attributes[transcode(xmlAttributes.getName(i))] = attrValue; context.attributes[transcode(xmlAttributes.getName(i))] = attrValue;
@ -172,7 +178,7 @@ void SceneHandler::endElement(const XMLCh* const xmlName) {
} else if (name == "ref") { } else if (name == "ref") {
std::string id = context.attributes["id"]; std::string id = context.attributes["id"];
if (m_namedObjects->find(id) == m_namedObjects->end()) if (m_namedObjects->find(id) == m_namedObjects->end())
SLog(EError, "Referenced object '%s' not found!", id.c_str()); XMLLog(EError, "Referenced object '%s' not found!", id.c_str());
object = (*m_namedObjects)[id]; object = (*m_namedObjects)[id];
/* Construct properties */ /* Construct properties */
} else if (name == "integer") { } else if (name == "integer") {
@ -183,7 +189,7 @@ void SceneHandler::endElement(const XMLCh* const xmlName) {
int64_t i = strtoll(context.attributes["value"].c_str(), &end_ptr, 10); int64_t i = strtoll(context.attributes["value"].c_str(), &end_ptr, 10);
#endif #endif
if (*end_ptr != '\0') if (*end_ptr != '\0')
SLog(EError, "Invalid integer value specified (in <%s>)", XMLLog(EError, "Invalid integer value specified (in <%s>)",
context.attributes["name"].c_str()); context.attributes["name"].c_str());
context.parent->properties.setLong(context.attributes["name"], i); context.parent->properties.setLong(context.attributes["name"], i);
} else if (name == "float") { } else if (name == "float") {
@ -239,7 +245,7 @@ void SceneHandler::endElement(const XMLCh* const xmlName) {
Float x=0, y=0, z=0; Float x=0, y=0, z=0;
if (hasXYZ && hasValue) { if (hasXYZ && hasValue) {
SLog(EError, "<scale>: provided both xyz and value arguments!"); XMLLog(EError, "<scale>: provided both xyz and value arguments!");
} else if (hasXYZ) { } else if (hasXYZ) {
x = parseFloat(name, context.attributes["x"], 1); x = parseFloat(name, context.attributes["x"], 1);
y = parseFloat(name, context.attributes["y"], 1); y = parseFloat(name, context.attributes["y"], 1);
@ -247,7 +253,7 @@ void SceneHandler::endElement(const XMLCh* const xmlName) {
} else if (hasValue) { } else if (hasValue) {
x = y = z = parseFloat(name, context.attributes["value"]); x = y = z = parseFloat(name, context.attributes["value"]);
} else { } else {
SLog(EError, "<scale>: provided neither xyz nor value arguments!"); XMLLog(EError, "<scale>: provided neither xyz nor value arguments!");
} }
m_transform = Transform::scale(Vector(x, y, z)) * m_transform; m_transform = Transform::scale(Vector(x, y, z)) * m_transform;
@ -255,7 +261,7 @@ void SceneHandler::endElement(const XMLCh* const xmlName) {
std::vector<std::string> tokens = tokenize( std::vector<std::string> tokens = tokenize(
context.attributes["value"], ", "); context.attributes["value"], ", ");
if (tokens.size() != 16) if (tokens.size() != 16)
SLog(EError, "Invalid matrix specified"); XMLLog(EError, "Invalid matrix specified");
int index = 0; int index = 0;
Matrix4x4 mtx; Matrix4x4 mtx;
@ -279,7 +285,7 @@ void SceneHandler::endElement(const XMLCh* const xmlName) {
/* Parse HTML-style hexadecimal colors */ /* Parse HTML-style hexadecimal colors */
int encoded = strtol(tokens[0].c_str()+1, &end_ptr, 16); int encoded = strtol(tokens[0].c_str()+1, &end_ptr, 16);
if (*end_ptr != '\0') if (*end_ptr != '\0')
SLog(EError, "Invalid rgb value specified (in <%s>)", context.attributes["name"].c_str()); XMLLog(EError, "Invalid rgb value specified (in <%s>)", context.attributes["name"].c_str());
value[0] = ((encoded & 0xFF0000) >> 16) / 255.0f; value[0] = ((encoded & 0xFF0000) >> 16) / 255.0f;
value[1] = ((encoded & 0x00FF00) >> 8) / 255.0f; value[1] = ((encoded & 0x00FF00) >> 8) / 255.0f;
value[2] = (encoded & 0x0000FF) / 255.0f; value[2] = (encoded & 0x0000FF) / 255.0f;
@ -290,7 +296,7 @@ void SceneHandler::endElement(const XMLCh* const xmlName) {
value[i] = parseFloat(name, tokens[i]); value[i] = parseFloat(name, tokens[i]);
} else { } else {
value[0] = value[1] = value[2] = 0; // avoid warning value[0] = value[1] = value[2] = 0; // avoid warning
SLog(EError, "Invalid RGB value specified"); XMLLog(EError, "Invalid RGB value specified");
} }
Spectrum specValue; Spectrum specValue;
specValue.fromLinearRGB(value[0], value[1], value[2]); specValue.fromLinearRGB(value[0], value[1], value[2]);
@ -305,7 +311,7 @@ void SceneHandler::endElement(const XMLCh* const xmlName) {
/* Parse HTML-style hexadecimal colors */ /* Parse HTML-style hexadecimal colors */
int encoded = strtol(tokens[0].c_str()+1, &end_ptr, 16); int encoded = strtol(tokens[0].c_str()+1, &end_ptr, 16);
if (*end_ptr != '\0') if (*end_ptr != '\0')
SLog(EError, "Invalid sRGB value specified (in <%s>)", context.attributes["name"].c_str()); XMLLog(EError, "Invalid sRGB value specified (in <%s>)", context.attributes["name"].c_str());
value[0] = ((encoded & 0xFF0000) >> 16) / 255.0f; value[0] = ((encoded & 0xFF0000) >> 16) / 255.0f;
value[1] = ((encoded & 0x00FF00) >> 8) / 255.0f; value[1] = ((encoded & 0x00FF00) >> 8) / 255.0f;
value[2] = (encoded & 0x0000FF) / 255.0f; value[2] = (encoded & 0x0000FF) / 255.0f;
@ -316,7 +322,7 @@ void SceneHandler::endElement(const XMLCh* const xmlName) {
value[i] = parseFloat(name, tokens[i]); value[i] = parseFloat(name, tokens[i]);
} else { } else {
value[0] = value[1] = value[2] = 0; // avoid warning value[0] = value[1] = value[2] = 0; // avoid warning
SLog(EError, "Invalid sRGB value specified"); XMLLog(EError, "Invalid sRGB value specified");
} }
Spectrum specValue; Spectrum specValue;
specValue.fromSRGB(value[0], value[1], value[2]); specValue.fromSRGB(value[0], value[1], value[2]);
@ -343,7 +349,7 @@ void SceneHandler::endElement(const XMLCh* const xmlName) {
for (size_t i=0; i<tokens.size(); i++) { for (size_t i=0; i<tokens.size(); i++) {
std::vector<std::string> tokens2 = tokenize(tokens[i], ":"); std::vector<std::string> tokens2 = tokenize(tokens[i], ":");
if (tokens2.size() != 2) if (tokens2.size() != 2)
SLog(EError, "Invalid spectrum->value mapping specified"); XMLLog(EError, "Invalid spectrum->value mapping specified");
Float wavelength = parseFloat(name, tokens2[0]); Float wavelength = parseFloat(name, tokens2[0]);
Float value = parseFloat(name, tokens2[1]); Float value = parseFloat(name, tokens2[1]);
interp.appendSample(wavelength, value); interp.appendSample(wavelength, value);
@ -354,7 +360,7 @@ void SceneHandler::endElement(const XMLCh* const xmlName) {
discrete); discrete);
} else { } else {
if (tokens.size() != SPECTRUM_SAMPLES) if (tokens.size() != SPECTRUM_SAMPLES)
SLog(EError, "Invalid spectrum value specified (incorrect length)"); XMLLog(EError, "Invalid spectrum value specified (incorrect length)");
for (int i=0; i<SPECTRUM_SAMPLES; i++) for (int i=0; i<SPECTRUM_SAMPLES; i++)
value[i] = parseFloat(name, tokens[i]); value[i] = parseFloat(name, tokens[i]);
context.parent->properties.setSpectrum(context.attributes["name"], context.parent->properties.setSpectrum(context.attributes["name"],
@ -377,19 +383,20 @@ void SceneHandler::endElement(const XMLCh* const xmlName) {
parser->setExternalNoNamespaceSchemaLocation(schemaPath.file_string().c_str()); parser->setExternalNoNamespaceSchemaLocation(schemaPath.file_string().c_str());
/* Set the handler and start parsing */ /* Set the handler and start parsing */
SceneHandler *handler = new SceneHandler(m_params, m_namedObjects, true); SceneHandler *handler = new SceneHandler(parser, m_params, m_namedObjects, true);
parser->setDoNamespaces(true); parser->setDoNamespaces(true);
parser->setDocumentHandler(handler); parser->setDocumentHandler(handler);
parser->setErrorHandler(handler); parser->setErrorHandler(handler);
parser->setCalculateSrcOfs(true);
fs::path path = resolver->resolve(context.attributes["filename"]); fs::path path = resolver->resolve(context.attributes["filename"]);
SLog(EInfo, "Parsing included file \"%s\" ..", path.filename().c_str()); XMLLog(EInfo, "Parsing included file \"%s\" ..", path.filename().c_str());
parser->parse(path.file_string().c_str()); parser->parse(path.file_string().c_str());
object = handler->getScene(); object = handler->getScene();
delete parser; delete parser;
delete handler; delete handler;
} else { } else {
SLog(EError, "Unhandled tag \"%s\" encountered!", name.c_str()); XMLLog(EError, "Unhandled tag \"%s\" encountered!", name.c_str());
} }
if (object != NULL) { if (object != NULL) {
@ -398,7 +405,7 @@ void SceneHandler::endElement(const XMLCh* const xmlName) {
if (id != "" && name != "ref") { if (id != "" && name != "ref") {
if (m_namedObjects->find(id) != m_namedObjects->end()) if (m_namedObjects->find(id) != m_namedObjects->end())
SLog(EError, "Duplicate ID '%s' used in scene description!", id.c_str()); XMLLog(EError, "Duplicate ID '%s' used in scene description!", id.c_str());
(*m_namedObjects)[id] = object; (*m_namedObjects)[id] = object;
object->incRef(); object->incRef();
} }
@ -427,7 +434,7 @@ void SceneHandler::endElement(const XMLCh* const xmlName) {
/* Warn about unqueried properties */ /* Warn about unqueried properties */
std::vector<std::string> unq = context.properties.getUnqueried(); std::vector<std::string> unq = context.properties.getUnqueried();
for (unsigned int i=0; i<unq.size(); ++i) for (unsigned int i=0; i<unq.size(); ++i)
SLog(EWarn, "Unqueried attribute \"%s\" in element \"%s\"", unq[i].c_str(), name.c_str()); XMLLog(EWarn, "Unqueried attribute \"%s\" in element \"%s\"", unq[i].c_str(), name.c_str());
m_context.pop(); m_context.pop();
} }

View File

@ -27,7 +27,7 @@
MTS_NAMESPACE_BEGIN MTS_NAMESPACE_BEGIN
Shape::Shape(const Properties &props) Shape::Shape(const Properties &props)
: ConfigurableObject(props) { } : ConfigurableObject(props), m_occluder(false) { }
Shape::Shape(Stream *stream, InstanceManager *manager) Shape::Shape(Stream *stream, InstanceManager *manager)
: ConfigurableObject(stream, manager) { : ConfigurableObject(stream, manager) {
@ -36,10 +36,10 @@ Shape::Shape(Stream *stream, InstanceManager *manager)
m_luminaire = static_cast<Luminaire *>(manager->getInstance(stream)); m_luminaire = static_cast<Luminaire *>(manager->getInstance(stream));
m_interiorMedium = static_cast<Medium *>(manager->getInstance(stream)); m_interiorMedium = static_cast<Medium *>(manager->getInstance(stream));
m_exteriorMedium = static_cast<Medium *>(manager->getInstance(stream)); m_exteriorMedium = static_cast<Medium *>(manager->getInstance(stream));
m_occluder = stream->readBool();
} }
Shape::~Shape() { Shape::~Shape() { }
}
void Shape::configure() { } void Shape::configure() { }
@ -68,12 +68,11 @@ Float Shape::sampleSolidAngle(ShapeSamplingRecord &sRec,
Float pdfArea = sampleArea(sRec, sample); Float pdfArea = sampleArea(sRec, sample);
Vector lumToPoint = from - sRec.p; Vector lumToPoint = from - sRec.p;
Float distSquared = lumToPoint.lengthSquared(), dp = dot(lumToPoint, sRec.n); Float distSquared = lumToPoint.lengthSquared(), dp = dot(lumToPoint, sRec.n);
if (dp > 0) { if (dp > 0)
return pdfArea * distSquared * std::sqrt(distSquared) / dp; return pdfArea * distSquared * std::sqrt(distSquared) / dp;
} else { else
return 0.0f; return 0.0f;
} }
}
Float Shape::pdfSolidAngle(const ShapeSamplingRecord &sRec, const Point &from) const { Float Shape::pdfSolidAngle(const ShapeSamplingRecord &sRec, const Point &from) const {
/* Turns the area sampling routine into one that samples wrt. solid angles */ /* Turns the area sampling routine into one that samples wrt. solid angles */
@ -87,6 +86,7 @@ void Shape::addChild(const std::string &name, ConfigurableObject *child) {
const Class *cClass = child->getClass(); const Class *cClass = child->getClass();
if (cClass->derivesFrom(MTS_CLASS(BSDF))) { if (cClass->derivesFrom(MTS_CLASS(BSDF))) {
m_bsdf = static_cast<BSDF *>(child); m_bsdf = static_cast<BSDF *>(child);
m_occluder = true;
} else if (cClass->derivesFrom(MTS_CLASS(Luminaire))) { } else if (cClass->derivesFrom(MTS_CLASS(Luminaire))) {
Assert(m_luminaire == NULL); Assert(m_luminaire == NULL);
m_luminaire = static_cast<Luminaire *>(child); m_luminaire = static_cast<Luminaire *>(child);
@ -120,6 +120,7 @@ void Shape::serialize(Stream *stream, InstanceManager *manager) const {
manager->serialize(stream, m_luminaire.get()); manager->serialize(stream, m_luminaire.get());
manager->serialize(stream, m_interiorMedium.get()); manager->serialize(stream, m_interiorMedium.get());
manager->serialize(stream, m_exteriorMedium.get()); manager->serialize(stream, m_exteriorMedium.get());
stream->writeBool(m_occluder);
} }
bool Shape::rayIntersect(const Ray &ray, Float mint, bool Shape::rayIntersect(const Ray &ray, Float mint,

View File

@ -36,9 +36,10 @@ ref<Scene> Utility::loadScene(const std::string &filename,
parser->setValidationSchemaFullChecking(true); parser->setValidationSchemaFullChecking(true);
parser->setValidationScheme(SAXParser::Val_Always); parser->setValidationScheme(SAXParser::Val_Always);
parser->setExternalNoNamespaceSchemaLocation(schemaPath.file_string().c_str()); parser->setExternalNoNamespaceSchemaLocation(schemaPath.file_string().c_str());
parser->setCalculateSrcOfs(true);
std::map<std::string, std::string> parameters; std::map<std::string, std::string> parameters;
SceneHandler *handler = new SceneHandler(params); SceneHandler *handler = new SceneHandler(parser, params);
parser->setDoNamespaces(true); parser->setDoNamespaces(true);
parser->setDocumentHandler(handler); parser->setDocumentHandler(handler);
parser->setErrorHandler(handler); parser->setErrorHandler(handler);

View File

@ -311,9 +311,10 @@ int ubi_main(int argc, char **argv) {
parser->setValidationSchemaFullChecking(true); parser->setValidationSchemaFullChecking(true);
parser->setValidationScheme(SAXParser::Val_Always); parser->setValidationScheme(SAXParser::Val_Always);
parser->setExternalNoNamespaceSchemaLocation(schemaPath.file_string().c_str()); parser->setExternalNoNamespaceSchemaLocation(schemaPath.file_string().c_str());
parser->setCalculateSrcOfs(true);
/* Set the handler */ /* Set the handler */
SceneHandler *handler = new SceneHandler(parameters); SceneHandler *handler = new SceneHandler(parser, parameters);
parser->setDoNamespaces(true); parser->setDoNamespaces(true);
parser->setDocumentHandler(handler); parser->setDocumentHandler(handler);
parser->setErrorHandler(handler); parser->setErrorHandler(handler);

View File

@ -39,7 +39,8 @@ void SceneLoader::run() {
for(size_t i=0; i<m_filename.size();++i) for(size_t i=0; i<m_filename.size();++i)
lowerCase[i] = std::tolower(m_filename[i]); lowerCase[i] = std::tolower(m_filename[i]);
SceneHandler *handler = new SceneHandler(SceneHandler::ParameterMap()); SceneHandler *handler = new SceneHandler(parser,
SceneHandler::ParameterMap());
m_result = new SceneContext(); m_result = new SceneContext();
try { try {
QSettings settings("mitsuba-renderer.org", "qtgui"); QSettings settings("mitsuba-renderer.org", "qtgui");
@ -73,6 +74,7 @@ void SceneLoader::run() {
parser->setValidationSchemaFullChecking(true); parser->setValidationSchemaFullChecking(true);
parser->setValidationScheme(SAXParser::Val_Always); parser->setValidationScheme(SAXParser::Val_Always);
parser->setExternalNoNamespaceSchemaLocation(schemaPath.file_string().c_str()); parser->setExternalNoNamespaceSchemaLocation(schemaPath.file_string().c_str());
parser->setCalculateSrcOfs(true);
/* Set the SAX handler */ /* Set the SAX handler */
parser->setDoNamespaces(true); parser->setDoNamespaces(true);

View File

@ -32,6 +32,7 @@ public:
Log(EInfo, "Loading animation track from \"%s\"", m_name.c_str()); Log(EInfo, "Loading animation track from \"%s\"", m_name.c_str());
ref<FileStream> fs = new FileStream(path, FileStream::EReadOnly); ref<FileStream> fs = new FileStream(path, FileStream::EReadOnly);
m_occluder = true;
m_transform = new AnimatedTransform(fs); m_transform = new AnimatedTransform(fs);
} }
@ -39,6 +40,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);
m_occluder = true;
configure(); configure();
} }

View File

@ -23,6 +23,7 @@ MTS_NAMESPACE_BEGIN
Instance::Instance(const Properties &props) : Shape(props) { Instance::Instance(const Properties &props) : Shape(props) {
m_objectToWorld = props.getTransform("toWorld", Transform()); m_objectToWorld = props.getTransform("toWorld", Transform());
m_worldToObject = m_objectToWorld.inverse(); m_worldToObject = m_objectToWorld.inverse();
m_occluder = true;
} }
Instance::Instance(Stream *stream, InstanceManager *manager) Instance::Instance(Stream *stream, InstanceManager *manager)
@ -30,6 +31,7 @@ Instance::Instance(Stream *stream, InstanceManager *manager)
m_shapeGroup = static_cast<ShapeGroup *>(manager->getInstance(stream)); m_shapeGroup = static_cast<ShapeGroup *>(manager->getInstance(stream));
m_objectToWorld = Transform(stream); m_objectToWorld = Transform(stream);
m_worldToObject = m_objectToWorld.inverse(); m_worldToObject = m_objectToWorld.inverse();
m_occluder = true;
} }
void Instance::serialize(Stream *stream, InstanceManager *manager) const { void Instance::serialize(Stream *stream, InstanceManager *manager) const {

View File

@ -253,7 +253,10 @@ public:
std::string toString() const { std::string toString() const {
std::ostringstream oss; std::ostringstream oss;
oss << "LDRTexture[filename=\"" << m_filename << "\", gamma=" << m_gamma << "]"; oss << "LDRTexture[" << endl
<< " filename = \"" << m_filename << "\"," << endl
<< " gamma = " << m_gamma << endl
<< "]";
return oss.str(); return oss.str();
} }

View File

@ -45,7 +45,7 @@ struct Vector3iKeyOrder : public std::binary_function<Vector3i, Vector3i, bool>
/** /**
* This class sits in between the renderer and another data source, for which * This class sits in between the renderer and another data source, for which
* caches all data lookups using a LRU scheme. This is useful if the nested * it caches all data lookups using a LRU scheme. This is useful if the nested
* volume data source is expensive to evaluate. * volume data source is expensive to evaluate.
*/ */
class CachingDataSource : public VolumeDataSource { class CachingDataSource : public VolumeDataSource {
@ -90,6 +90,9 @@ public:
if (m_nested == NULL) if (m_nested == NULL)
Log(EError, "A nested volume data source is needed!"); Log(EError, "A nested volume data source is needed!");
m_aabb = m_nested->getAABB(); m_aabb = m_nested->getAABB();
if (!m_aabb.isValid())
Log(EError, "Nested axis-aligned bounding box was invalid!");
if (m_voxelWidth == -1) if (m_voxelWidth == -1)
m_voxelWidth = m_nested->getStepSize(); m_voxelWidth = m_nested->getStepSize();
@ -260,8 +263,7 @@ public:
for (int z = 0; z<m_blockRes; ++z) { for (int z = 0; z<m_blockRes; ++z) {
for (int y = 0; y<m_blockRes; ++y) { for (int y = 0; y<m_blockRes; ++y) {
for (int x = 0; x<m_blockRes; ++x) { for (int x = 0; x<m_blockRes; ++x) {
Point p = offset + Vector(x + (Float) 0.5f, Point p = offset + Vector(x, y, z) * m_voxelWidth;
y + (Float) 0.5f, z + (Float) 0.5f) * m_voxelWidth;
float value = (float) m_nested->lookupFloat(p); float value = (float) m_nested->lookupFloat(p);
result[idx++] = value; result[idx++] = value;
nonempty |= (value != 0); nonempty |= (value != 0);