Nori

include/nori/object.h

Go to the documentation of this file.
00001 /*
00002     This file is part of Nori, a simple educational ray tracer
00003 
00004     Copyright (c) 2012 by Wenzel Jakob and Steve Marschner.
00005 
00006     Nori is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License Version 3
00008     as published by the Free Software Foundation.
00009 
00010     Nori is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program. If not, see <http://www.gnu.org/licenses/>.
00017 */
00018 
00019 #if !defined(__OBJECT_H)
00020 #define __OBJECT_H
00021 
00022 #include <nori/proplist.h>
00023 #include <boost/function.hpp>
00024 
00025 NORI_NAMESPACE_BEGIN
00026 
00027 /**
00028  * \brief Base class of all objects
00029  *
00030  * A Nori object represents an instance that is part of
00031  * a scene description, e.g. a scattering model or luminaire.
00032  */
00033 class NoriObject {
00034 public:
00035         enum EClassType {
00036                 EScene = 0,
00037                 EMesh,
00038                 EBSDF,
00039                 ELuminaire,
00040                 ECamera,
00041                 EIntegrator,
00042                 ESampler,
00043                 ETest,
00044                 EReconstructionFilter,
00045                 EClassTypeCount
00046         };
00047 
00048         /// Virtual destructor
00049         virtual ~NoriObject() { }
00050 
00051         /**
00052          * \brief Return the type of object (i.e. Mesh/BSDF/etc.) 
00053          * provided by this instance
00054          * */
00055         virtual EClassType getClassType() const = 0;
00056 
00057         /**
00058          * \brief Add a child object to the current instance
00059          *
00060          * The default implementation does not support children and
00061          * simply throws an exception
00062          */
00063         virtual void addChild(NoriObject *child);
00064 
00065         /**
00066          * \brief Set the parent object
00067          *
00068          * Subclasses may choose to override this method to be
00069          * notified when they are added to a parent object. The
00070          * default implementation does nothing.
00071          */
00072         virtual void setParent(NoriObject *parent);
00073 
00074         /**
00075          * \brief Perform some action associated with the object
00076          *
00077          * The default implementation throws an exception. Certain objects
00078          * may choose to override it, e.g. to implement initialization, 
00079          * testing, or rendering functionality.
00080          *
00081          * This function is called by the XML parser once it has
00082          * constructed an object and added all of its children
00083          * using \ref addChild().
00084          */
00085         virtual void activate();
00086 
00087         /// Return a brief string summary of the instance (for debugging purposes)
00088         virtual QString toString() const = 0;
00089         
00090         /// Turn a class type into a human-readable string
00091         inline static QString classTypeName(EClassType type) {
00092                 switch (type) {
00093                         case EScene:      return "scene";
00094                         case EMesh:       return "mesh";
00095                         case EBSDF:       return "bsdf";
00096                         case ELuminaire:  return "luminaire";
00097                         case ECamera:     return "camera";
00098                         case EIntegrator: return "integrator";
00099                         case ESampler:    return "sampler";
00100                         case ETest:       return "test";
00101                         default:          return "<unknown>";
00102                 }
00103         }
00104 };
00105 
00106 /**
00107  * \brief Factory for Nori objects
00108  *
00109  * This utility class is part of a mini-RTTI framework and can 
00110  * instantiate arbitrary Nori objects by their name.
00111  */
00112 class NoriObjectFactory {
00113 public:
00114         typedef boost::function<NoriObject *(const PropertyList &)> Constructor;
00115 
00116         /**
00117          * \brief Register an object constructor with the object factory
00118          *
00119          * This function is called by the macro \ref NORI_REGISTER_CLASS
00120          *
00121          * \param name
00122          *     An internal name that is associated with this class. This is the
00123          *     'type' field found in the scene description XML files
00124          *
00125          * \param constr
00126          *     A Boost function pointer to an anonymous function that is
00127          *     able to call the constructor of the class.
00128          */
00129         static void registerClass(const QString &name, const Constructor &constr);
00130 
00131         /**
00132          * \brief Construct an instance from the class of the given name
00133          *
00134          * \param name
00135          *     An internal name that is associated with this class. This is the
00136          *     'type' field found in the scene description XML files
00137          *
00138          * \param propList
00139          *     A list of properties that will be passed to the constructor
00140          *     of the class.
00141          */
00142         inline static NoriObject *createInstance(const QString &name,
00143                         const PropertyList &propList) {
00144                 if (m_constructors->find(name) == m_constructors->end())
00145                         throw NoriException(QString("A constructor for class '%1' "
00146                                 "could not be found!").arg(name));
00147                 return (*m_constructors)[name](propList);
00148         }
00149 private:
00150         static std::map<QString, Constructor> *m_constructors;
00151 };
00152 
00153 /// Macro for registering an object constructor with the \ref NoriObjectFactory
00154 #define NORI_REGISTER_CLASS(cls, name) \
00155         cls *cls ##_create(const PropertyList &list) { \
00156                 return new cls(list); \
00157         } \
00158         static struct cls ##_{ \
00159                 cls ##_() { \
00160                         NoriObjectFactory::registerClass(name, cls ##_create); \
00161                 } \
00162         } cls ##__;
00163 
00164 NORI_NAMESPACE_END
00165 
00166 #endif /* __OBJECT_H */
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines