/* 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 . */ #include #include MTS_NAMESPACE_BEGIN bool Properties::hasProperty(const std::string &name) const { return m_elements.find(name) != m_elements.end(); } std::vector Properties::getUnqueried() const { std::map::const_iterator it = m_elements.begin(); std::vector 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::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::const_iterator it = m_elements.find(name); if ((*it).second.type != EBoolean) SLog(EError, "The property \"%s\" has the wrong type (expected ). 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::const_iterator it = m_elements.find(name); if ((*it).second.type != EBoolean) SLog(EError, "The property \"%s\" has the wrong type (expected ). 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::const_iterator it = m_elements.find(name); if ((*it).second.type != EInteger) SLog(EError, "The property \"%s\" has the wrong type (expected ). 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::const_iterator it = m_elements.find(name); if ((*it).second.type != EInteger) SLog(EError, "The property \"%s\" has the wrong type (expected ). 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::const_iterator it = m_elements.find(name); if ((*it).second.type != EInteger) SLog(EError, "The property \"%s\" has the wrong type (expected ). 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::const_iterator it = m_elements.find(name); if ((*it).second.type != EInteger) SLog(EError, "The property \"%s\" has the wrong type (expected ). 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::const_iterator it = m_elements.find(name); if ((*it).second.type != EInteger) SLog(EError, "The property \"%s\" has the wrong type (expected ). 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::const_iterator it = m_elements.find(name); if ((*it).second.type != EInteger) SLog(EError, "The property \"%s\" has the wrong type (expected ). 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::const_iterator it = m_elements.find(name); if ((*it).second.type != EFloat) SLog(EError, "The property \"%s\" has the wrong type (expected ). 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::const_iterator it = m_elements.find(name); if ((*it).second.type != EFloat) SLog(EError, "The property \"%s\" has the wrong type (expected ). 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::const_iterator it = m_elements.find(name); if ((*it).second.type != ETransform) SLog(EError, "The property \"%s\" has the wrong type (expected ). 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::const_iterator it = m_elements.find(name); if ((*it).second.type != ETransform) SLog(EError, "The property \"%s\" has the wrong type (expected ). 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::const_iterator it = m_elements.find(name); if ((*it).second.type != ESpectrum) SLog(EError, "The property \"%s\" has the wrong type (expected ). 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::const_iterator it = m_elements.find(name); if ((*it).second.type != ESpectrum) SLog(EError, "The property \"%s\" has the wrong type (expected ). 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::const_iterator it = m_elements.find(name); if ((*it).second.type != EString) SLog(EError, "The property \"%s\" has the wrong type (expected ). 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::const_iterator it = m_elements.find(name); if ((*it).second.type != EString) SLog(EError, "The property \"%s\" has the wrong type (expected ). 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::const_iterator it = m_elements.find(name); if ((*it).second.type != EPoint) SLog(EError, "The property \"%s\" has the wrong type (expected ). 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::const_iterator it = m_elements.find(name); if ((*it).second.type != EPoint) SLog(EError, "The property \"%s\" has the wrong type (expected ). 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::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(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 ¶ms) { } MTS_IMPLEMENT_CLASS(ConfigurableObject, true, SerializableObject) MTS_IMPLEMENT_CLASS(NetworkedObject, true, ConfigurableObject) MTS_NAMESPACE_END