401 lines
15 KiB
C++
401 lines
15 KiB
C++
/*
|
|
This file is part of Mitsuba, a physically based rendering system.
|
|
|
|
Copyright (c) 2007-2011 by Wenzel Jakob and others.
|
|
|
|
Mitsuba is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License Version 3
|
|
as published by the Free Software Foundation.
|
|
|
|
Mitsuba is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <mitsuba/core/properties.h>
|
|
#include <mitsuba/core/netobject.h>
|
|
|
|
MTS_NAMESPACE_BEGIN
|
|
|
|
bool Properties::hasProperty(const std::string &name) const {
|
|
return m_elements.find(name) != m_elements.end();
|
|
}
|
|
|
|
std::vector<std::string> Properties::getUnqueried() const {
|
|
std::map<std::string, Element>::const_iterator it = m_elements.begin();
|
|
std::vector<std::string> result;
|
|
|
|
for (; it != m_elements.end(); ++it) {
|
|
if ((*it).second.queried == false)
|
|
result.push_back((*it).first);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
Properties::EPropertyType Properties::getType(const std::string &name) const {
|
|
std::map<std::string, Element>::const_iterator it = m_elements.find(name);
|
|
if (it == m_elements.end())
|
|
SLog(EError, "Property \"%s\" has not been specified!", name.c_str());
|
|
return (*it).second.type;
|
|
}
|
|
|
|
void Properties::setBoolean(const std::string &name, bool value, bool warnDuplicates) {
|
|
if (hasProperty(name) && warnDuplicates)
|
|
SLog(EWarn, "Property \"%s\" has already been specified!", name.c_str());
|
|
m_elements[name].type = EBoolean;
|
|
m_elements[name].v_boolean = value;
|
|
m_elements[name].queried = false;
|
|
}
|
|
|
|
bool Properties::getBoolean(const std::string &name) const {
|
|
if (!hasProperty(name))
|
|
SLog(EError, "Property \"%s\" missing", name.c_str());
|
|
std::map<std::string, Element>::const_iterator it = m_elements.find(name);
|
|
if ((*it).second.type != EBoolean)
|
|
SLog(EError, "The property \"%s\" has the wrong type (expected <boolean>). The detailed "
|
|
"listing was:\n%s", name.c_str(), toString().c_str());
|
|
(*it).second.queried = true;
|
|
return (*it).second.v_boolean;
|
|
}
|
|
|
|
bool Properties::getBoolean(const std::string &name, bool defVal) const {
|
|
if (!hasProperty(name))
|
|
return defVal;
|
|
std::map<std::string, Element>::const_iterator it = m_elements.find(name);
|
|
if ((*it).second.type != EBoolean)
|
|
SLog(EError, "The property \"%s\" has the wrong type (expected <boolean>). The detailed "
|
|
"listing was:\n%s", name.c_str(), toString().c_str());
|
|
(*it).second.queried = true;
|
|
return (*it).second.v_boolean;
|
|
}
|
|
|
|
void Properties::setInteger(const std::string &name, int value, bool warnDuplicates) {
|
|
if (hasProperty(name) && warnDuplicates)
|
|
SLog(EWarn, "Property \"%s\" has already been specified!", name.c_str());
|
|
m_elements[name].type = EInteger;
|
|
m_elements[name].v_long = value;
|
|
m_elements[name].queried = false;
|
|
}
|
|
|
|
int Properties::getInteger(const std::string &name) const {
|
|
if (!hasProperty(name))
|
|
SLog(EError, "Property \"%s\" missing", name.c_str());
|
|
std::map<std::string, Element>::const_iterator it = m_elements.find(name);
|
|
if ((*it).second.type != EInteger)
|
|
SLog(EError, "The property \"%s\" has the wrong type (expected <integer>). The detailed "
|
|
"listing was:\n%s", name.c_str(), toString().c_str());
|
|
(*it).second.queried = true;
|
|
return (int) (*it).second.v_long;
|
|
}
|
|
|
|
int Properties::getInteger(const std::string &name, int defVal) const {
|
|
if (!hasProperty(name))
|
|
return defVal;
|
|
std::map<std::string, Element>::const_iterator it = m_elements.find(name);
|
|
if ((*it).second.type != EInteger)
|
|
SLog(EError, "The property \"%s\" has the wrong type (expected <integer>). The detailed "
|
|
"listing was:\n%s", name.c_str(), toString().c_str());
|
|
(*it).second.queried = true;
|
|
return (int) (*it).second.v_long;
|
|
}
|
|
|
|
void Properties::setLong(const std::string &name, int64_t value, bool warnDuplicates) {
|
|
if (hasProperty(name) && warnDuplicates)
|
|
SLog(EWarn, "Property \"%s\" has already been specified!", name.c_str());
|
|
m_elements[name].type = EInteger;
|
|
m_elements[name].v_long = value;
|
|
m_elements[name].queried = false;
|
|
}
|
|
|
|
int64_t Properties::getLong(const std::string &name) const {
|
|
if (!hasProperty(name))
|
|
SLog(EError, "Property \"%s\" missing", name.c_str());
|
|
std::map<std::string, Element>::const_iterator it = m_elements.find(name);
|
|
if ((*it).second.type != EInteger)
|
|
SLog(EError, "The property \"%s\" has the wrong type (expected <integer>). The detailed "
|
|
"listing was:\n%s", name.c_str(), toString().c_str());
|
|
(*it).second.queried = true;
|
|
return (*it).second.v_long;
|
|
}
|
|
|
|
int64_t Properties::getLong(const std::string &name, int64_t defVal) const {
|
|
if (!hasProperty(name))
|
|
return defVal;
|
|
std::map<std::string, Element>::const_iterator it = m_elements.find(name);
|
|
if ((*it).second.type != EInteger)
|
|
SLog(EError, "The property \"%s\" has the wrong type (expected <integer>). The detailed "
|
|
"listing was:\n%s", name.c_str(), toString().c_str());
|
|
(*it).second.queried = true;
|
|
return (*it).second.v_long;
|
|
}
|
|
|
|
size_t Properties::getSize(const std::string &name) const {
|
|
if (!hasProperty(name))
|
|
SLog(EError, "Property \"%s\" missing", name.c_str());
|
|
std::map<std::string, Element>::const_iterator it = m_elements.find(name);
|
|
if ((*it).second.type != EInteger)
|
|
SLog(EError, "The property \"%s\" has the wrong type (expected <integer>). The detailed "
|
|
"listing was:\n%s", name.c_str(), toString().c_str());
|
|
if ((*it).second.v_long < 0)
|
|
SLog(EError, "Size property \"%s\": expected a nonnegative value!");
|
|
(*it).second.queried = true;
|
|
return (size_t) (*it).second.v_long;
|
|
}
|
|
|
|
size_t Properties::getSize(const std::string &name, size_t defVal) const {
|
|
if (!hasProperty(name))
|
|
return defVal;
|
|
std::map<std::string, Element>::const_iterator it = m_elements.find(name);
|
|
if ((*it).second.type != EInteger)
|
|
SLog(EError, "The property \"%s\" has the wrong type (expected <integer>). The detailed "
|
|
"listing was:\n%s", name.c_str(), toString().c_str());
|
|
if ((*it).second.v_long < 0)
|
|
SLog(EError, "Size property \"%s\": expected a nonnegative value!");
|
|
(*it).second.queried = true;
|
|
return (size_t) (*it).second.v_long;
|
|
}
|
|
|
|
|
|
void Properties::setFloat(const std::string &name, Float value, bool warnDuplicates) {
|
|
if (hasProperty(name) && warnDuplicates)
|
|
SLog(EWarn, "Property \"%s\" has already been specified!", name.c_str());
|
|
m_elements[name].type = EFloat;
|
|
m_elements[name].v_float = value;
|
|
m_elements[name].queried = false;
|
|
}
|
|
|
|
Float Properties::getFloat(const std::string &name) const {
|
|
if (!hasProperty(name))
|
|
SLog(EError, "Property \"%s\" missing", name.c_str());
|
|
std::map<std::string, Element>::const_iterator it = m_elements.find(name);
|
|
if ((*it).second.type != EFloat)
|
|
SLog(EError, "The property \"%s\" has the wrong type (expected <float>). The detailed "
|
|
"listing was:\n%s", name.c_str(), toString().c_str());
|
|
(*it).second.queried = true;
|
|
return (*it).second.v_float;
|
|
}
|
|
|
|
Float Properties::getFloat(const std::string &name, Float defVal) const {
|
|
if (!hasProperty(name))
|
|
return defVal;
|
|
std::map<std::string, Element>::const_iterator it = m_elements.find(name);
|
|
if ((*it).second.type != EFloat)
|
|
SLog(EError, "The property \"%s\" has the wrong type (expected <float>). The detailed "
|
|
"listing was:\n%s", name.c_str(), toString().c_str());
|
|
(*it).second.queried = true;
|
|
return (*it).second.v_float;
|
|
}
|
|
|
|
void Properties::setTransform(const std::string &name, const Transform &value, bool warnDuplicates) {
|
|
if (hasProperty(name) && warnDuplicates)
|
|
SLog(EWarn, "Property \"%s\" has already been specified!", name.c_str());
|
|
m_elements[name].type = ETransform;
|
|
m_elements[name].v_transform = value;
|
|
m_elements[name].queried = false;
|
|
}
|
|
|
|
Transform Properties::getTransform(const std::string &name) const {
|
|
if (!hasProperty(name))
|
|
SLog(EError, "Property \"%s\" missing", name.c_str());
|
|
std::map<std::string, Element>::const_iterator it = m_elements.find(name);
|
|
if ((*it).second.type != ETransform)
|
|
SLog(EError, "The property \"%s\" has the wrong type (expected <transform>). The detailed "
|
|
"listing was:\n%s", name.c_str(), toString().c_str());
|
|
(*it).second.queried = true;
|
|
return (*it).second.v_transform;
|
|
}
|
|
|
|
Transform Properties::getTransform(const std::string &name, const Transform &defVal) const {
|
|
if (!hasProperty(name))
|
|
return defVal;
|
|
std::map<std::string, Element>::const_iterator it = m_elements.find(name);
|
|
if ((*it).second.type != ETransform)
|
|
SLog(EError, "The property \"%s\" has the wrong type (expected <transform>). The detailed "
|
|
"listing was:\n%s", name.c_str(), toString().c_str());
|
|
(*it).second.queried = true;
|
|
return (*it).second.v_transform;
|
|
}
|
|
|
|
void Properties::setSpectrum(const std::string &name, const Spectrum &value, bool warnDuplicates) {
|
|
if (hasProperty(name) && warnDuplicates)
|
|
SLog(EWarn, "Property \"%s\" has already been specified!", name.c_str());
|
|
m_elements[name].type = ESpectrum;
|
|
m_elements[name].v_spectrum = value;
|
|
m_elements[name].queried = false;
|
|
}
|
|
|
|
Spectrum Properties::getSpectrum(const std::string &name) const {
|
|
if (!hasProperty(name))
|
|
SLog(EError, "Property \"%s\" missing", name.c_str());
|
|
std::map<std::string, Element>::const_iterator it = m_elements.find(name);
|
|
if ((*it).second.type != ESpectrum)
|
|
SLog(EError, "The property \"%s\" has the wrong type (expected <spectrum>). The detailed "
|
|
"listing was:\n%s", name.c_str(), toString().c_str());
|
|
(*it).second.queried = true;
|
|
return (*it).second.v_spectrum;
|
|
}
|
|
|
|
Spectrum Properties::getSpectrum(const std::string &name, const Spectrum &defVal) const {
|
|
if (!hasProperty(name))
|
|
return defVal;
|
|
std::map<std::string, Element>::const_iterator it = m_elements.find(name);
|
|
if ((*it).second.type != ESpectrum)
|
|
SLog(EError, "The property \"%s\" has the wrong type (expected <spectrum>). The detailed "
|
|
"listing was:\n%s", name.c_str(), toString().c_str());
|
|
(*it).second.queried = true;
|
|
return (*it).second.v_spectrum;
|
|
}
|
|
|
|
void Properties::setString(const std::string &name, const std::string &value, bool warnDuplicates) {
|
|
if (hasProperty(name) && warnDuplicates)
|
|
SLog(EWarn, "Property \"%s\" has already been specified!", name.c_str());
|
|
m_elements[name].type = EString;
|
|
m_elements[name].v_string = value;
|
|
m_elements[name].queried = false;
|
|
}
|
|
|
|
std::string Properties::getString(const std::string &name) const {
|
|
if (!hasProperty(name))
|
|
SLog(EError, "Property \"%s\" missing", name.c_str());
|
|
std::map<std::string, Element>::const_iterator it = m_elements.find(name);
|
|
if ((*it).second.type != EString)
|
|
SLog(EError, "The property \"%s\" has the wrong type (expected <string>). The detailed "
|
|
"listing was:\n%s", name.c_str(), toString().c_str());
|
|
(*it).second.queried = true;
|
|
return (*it).second.v_string;
|
|
}
|
|
|
|
std::string Properties::getString(const std::string &name, const std::string &defVal) const {
|
|
if (!hasProperty(name))
|
|
return defVal;
|
|
std::map<std::string, Element>::const_iterator it = m_elements.find(name);
|
|
if ((*it).second.type != EString)
|
|
SLog(EError, "The property \"%s\" has the wrong type (expected <string>). The detailed "
|
|
"listing was:\n%s", name.c_str(), toString().c_str());
|
|
(*it).second.queried = true;
|
|
return (*it).second.v_string;
|
|
}
|
|
|
|
void Properties::setPoint(const std::string &name, const Point &value, bool warnDuplicates) {
|
|
if (hasProperty(name) && warnDuplicates)
|
|
SLog(EWarn, "Property \"%s\" has already been specified!", name.c_str());
|
|
m_elements[name].type = EPoint;
|
|
m_elements[name].v_point = value;
|
|
m_elements[name].queried = false;
|
|
}
|
|
|
|
Vector Properties::getVector(const std::string &name) const {
|
|
return Vector(getPoint(name));
|
|
}
|
|
|
|
Vector Properties::getVector(const std::string &name, const Vector &defVal) const {
|
|
return Vector(getPoint(name, Point(defVal)));
|
|
}
|
|
|
|
Point Properties::getPoint(const std::string &name) const {
|
|
if (!hasProperty(name))
|
|
SLog(EError, "Property \"%s\" missing", name.c_str());
|
|
std::map<std::string, Element>::const_iterator it = m_elements.find(name);
|
|
if ((*it).second.type != EPoint)
|
|
SLog(EError, "The property \"%s\" has the wrong type (expected <point>). The detailed "
|
|
"listing was:\n%s", name.c_str(), toString().c_str());
|
|
(*it).second.queried = true;
|
|
return (*it).second.v_point;
|
|
}
|
|
|
|
Point Properties::getPoint(const std::string &name, const Point &defVal) const {
|
|
if (!hasProperty(name))
|
|
return defVal;
|
|
std::map<std::string, Element>::const_iterator it = m_elements.find(name);
|
|
if ((*it).second.type != EPoint)
|
|
SLog(EError, "The property \"%s\" has the wrong type (expected <point>). The detailed "
|
|
"listing was:\n%s", name.c_str(), toString().c_str());
|
|
(*it).second.queried = true;
|
|
return (*it).second.v_point;
|
|
}
|
|
|
|
std::string Properties::toString() const {
|
|
std::map<std::string, Element>::const_iterator it = m_elements.begin();
|
|
std::ostringstream oss;
|
|
|
|
oss << "Properties[" << endl
|
|
<< " pluginName = \"" << m_pluginName << "\"," << endl
|
|
<< " elements = {" << endl;
|
|
for (; it != m_elements.end(); ++it) {
|
|
oss << " \"" << (*it).first << "\" -> ";
|
|
const Element &el = (*it).second;
|
|
switch (el.type) {
|
|
case EBoolean:
|
|
oss << (el.v_boolean ? "true" : "false");
|
|
break;
|
|
case EInteger:
|
|
oss << el.v_long;
|
|
break;
|
|
case EFloat:
|
|
oss << el.v_float;
|
|
break;
|
|
case EPoint:
|
|
oss << el.v_point.toString();
|
|
break;
|
|
case ETransform:
|
|
oss << el.v_transform.toString();
|
|
break;
|
|
case ESpectrum:
|
|
oss << el.v_spectrum.toString();
|
|
break;
|
|
case EString:
|
|
oss << "\"" << el.v_string << "\"";
|
|
break;
|
|
default:
|
|
SLog(EError, "Encountered an unknown property type!");
|
|
}
|
|
oss << "," << endl;
|
|
}
|
|
oss << " }" << endl
|
|
<< "]" << endl;
|
|
return oss.str();
|
|
}
|
|
|
|
ConfigurableObject::ConfigurableObject(Stream *stream, InstanceManager *manager)
|
|
: SerializableObject(stream, manager), m_configured(true) {
|
|
m_parent = static_cast<ConfigurableObject *>(manager->getInstance(stream));
|
|
}
|
|
|
|
void ConfigurableObject::setParent(ConfigurableObject *parent) {
|
|
m_parent = parent;
|
|
}
|
|
|
|
void ConfigurableObject::configure() {
|
|
}
|
|
|
|
void ConfigurableObject::serialize(Stream *stream, InstanceManager *manager) const {
|
|
if (!getClass()->isSerializable())
|
|
Log(EError, "Error: trying to serialize an instance of type '%s', which does "
|
|
"not have full serialization support!", getClass()->getName().c_str());
|
|
manager->serialize(stream, m_parent);
|
|
}
|
|
|
|
void ConfigurableObject::addChild(const std::string &name, ConfigurableObject *child) {
|
|
SLog(EError, "ConfigurableObject::addChild(\"%s\", %s) not implemented in \"%s\"",
|
|
name.c_str(), child->toString().c_str(), toString().c_str());
|
|
}
|
|
|
|
void NetworkedObject::serialize(Stream *stream, InstanceManager *manager) const {
|
|
ConfigurableObject::serialize(stream, manager);
|
|
}
|
|
|
|
void NetworkedObject::bindUsedResources(ParallelProcess *proc) const {
|
|
}
|
|
|
|
void NetworkedObject::wakeup(std::map<std::string, SerializableObject *> ¶ms) {
|
|
}
|
|
|
|
MTS_IMPLEMENT_CLASS(ConfigurableObject, true, SerializableObject)
|
|
MTS_IMPLEMENT_CLASS(NetworkedObject, true, ConfigurableObject)
|
|
MTS_NAMESPACE_END
|