more source-level documentation

metadata
Wenzel Jakob 2010-09-15 21:15:42 +02:00
parent 768bacccdc
commit 7a18e43123
12 changed files with 331 additions and 226 deletions

View File

@ -23,7 +23,7 @@
MTS_NAMESPACE_BEGIN
/** \brief Console stream
/** \brief Interface to the default stdin/stdout console streams
*/
class MTS_EXPORT_CORE ConsoleStream : public Stream {
public:

View File

@ -38,9 +38,10 @@ MTS_NAMESPACE_BEGIN
class MTS_EXPORT_CORE FileResolver : public Object {
public:
/**
* Create a new file resolver containing the
* current working directory as the initial
* search path.
* \brief Create a new file resolver with the default settings
*
* Create a new file resolver containing the current working
* directory as the initial search path.
*/
FileResolver();

View File

@ -24,8 +24,7 @@
MTS_NAMESPACE_BEGIN
/**
* Uniform 3D grid for storing arbitrary quantities, which can
* be queried and updated by rasterizing rays to the grid.
* \brief Uniform 3D grid for storing and manipulating arbitrary quantities
*/
template <typename ValueType> class Grid {
public:
@ -82,7 +81,7 @@ public:
/// Return the grid AABB
inline const AABB &getAABB() const { return m_aabb; }
/// Return the grid resolution
inline const Vector3i &getResolution() const { return m_res; }
@ -98,7 +97,7 @@ public:
inline const ValueType &operator()(int x, int y, int z) const {
return m_cells[x + y*m_res.x + z*m_slab];
}
/// Return the underlying array
/// Return a pointer to the underlying array
inline ValueType *getData() const { return m_cells; }
/// Return a string representation
@ -172,7 +171,10 @@ public:
return true;
}
/// Rasterize a ray to the grid
/**
* \brief Rasterize a ray to the grid and apply the functor to
* every traversed cell
*/
template <typename Functor> void rasterize(const Ray &ray, Functor &functor) {
Float mint, maxt, t;

View File

@ -25,9 +25,10 @@
MTS_NAMESPACE_BEGIN
/**
* Templated multiple-reference octree. Based on the excellent
* implementation in PBRT. Modifications are the addition of a
* bounding sphere query and support for multithreading.
* \brief Generic multiple-reference octree.
*
* Based on the excellent implementation in PBRT. Modifications are
* the addition of a bounding sphere query and support for multithreading.
*/
template <typename T> class Octree {
public:

View File

@ -86,12 +86,17 @@
MTS_NAMESPACE_BEGIN
/**
* \brief %Random number generator based on Mersenne Twister
* by Takuji Nishimura and Makoto Matsumoto.
*/
class MTS_EXPORT_CORE Random : public SerializableObject {
public:
/**
* Construct a new seeded random generator. Uses the default
* seed on Windows and '/dev/urandom' on OSX and Linux.
* \brief Construct a new seeded random generator.
*
* Uses the default seed on Windows and '/dev/urandom'
* on OSX and Linux.
*/
Random();
@ -123,8 +128,10 @@ public:
Float nextFloat();
/**
* Draw a uniformly distributed permutation and permute the given STL container
* (see Knuth, TAoCP Vol. 2 (3rd 3d), Section 3.4.2)
* \brief Draw a uniformly distributed permutation and permute the
* given STL container.
*
* See Knuth, TAoCP Vol. 2 (3rd 3d), Section 3.4.2.
*/
template <typename Iterator> void shuffle(Iterator it1, Iterator it2) {
for (Iterator it = it2 - 1; it > it1; --it)

View File

@ -102,7 +102,7 @@ struct Ray {
}
};
/** \brief Ray differential -- enhances the basic ray class with
/** \brief %Ray differential -- enhances the basic ray class with
information about the rays of adjacent pixels on the view plane */
struct RayDifferential : public Ray {
bool hasDifferentials;
@ -119,16 +119,29 @@ struct RayDifferential : public Ray {
inline explicit RayDifferential(const Ray &ray)
: Ray(ray), hasDifferentials(false) {
}
inline RayDifferential(const RayDifferential &ray)
: Ray(ray), hasDifferentials(ray.hasDifferentials), rx(ray.rx), ry(ray.ry) {
}
inline void operator=(const RayDifferential &ray) {
o = ray.o;
mint = ray.mint;
d = ray.d;
maxt = ray.maxt;
dRcp = ray.dRcp;
hasDifferentials = ray.hasDifferentials;
rx = ray.rx;
ry = ray.ry;
}
inline void operator=(const Ray &ray) {
setOrigin(ray.o);
setDirection(ray.d);
o = ray.o;
mint = ray.mint;
d = ray.d;
maxt = ray.maxt;
dRcp = ray.dRcp;
hasDifferentials = false;
}
};

View File

@ -32,7 +32,7 @@
MTS_NAMESPACE_BEGIN
/**
* Abstract work unit. Represents a small amount of information
* \brief Abstract work unit -- represents a small amount of information
* that encodes part of a larger processing task.
*/
class MTS_EXPORT_CORE WorkUnit : public Object {
@ -56,8 +56,8 @@ protected:
};
/**
* Abstract work result. Represents the information that encodes
* the result of a processed <tt>WorkUnit</tt> instance.
* \brief Abstract work result -- represents the result of a
* processed <tt>\ref WorkUnit</tt> instance.
*/
class MTS_EXPORT_CORE WorkResult : public Object {
public:
@ -77,30 +77,28 @@ protected:
};
/**
* Abstract work processor. Takes work units and turns them into
* <tt>WorkResult</tt> instances. The class is serializable so that
* it can be sent over the network if required. It is possible to
* keep local state in <tt>WorkProcessor</tt> instances (e.g. scratch
* space for computations), though anything not returned in the form
* of <tt>WorkResult</tt>s will eventually be lost. Each worker
* (both locally and remotely) has its own <tt>WorkProcessor</tt>,
* and therefore no form of locking is required.
* \brief Abstract work processor -- takes work units and turns them into
* <tt>WorkResult</tt> instances.
*
* The class is serializable so that it can be sent over the network if
* required. It is possible to keep local state in <tt>WorkProcessor</tt>
* instances (e.g. scratch space for computations), though anything not
* returned in the form of <tt>WorkResult</tt>s will eventually be lost.
* Each worker (both locally and remotely) has its own <tt>WorkProcessor</tt>,
* and therefore no form of locking is required within instances of this class.
*/
class MTS_EXPORT_CORE WorkProcessor : public SerializableObject {
friend class Scheduler;
public:
/**
* Create a work unit of the proper type and size.
*/
/// Create a work unit of the proper type and size.
virtual ref<WorkUnit> createWorkUnit() const = 0;
/**
* Create a work result of the proper type and size
*/
/// Create a work result of the proper type and size
virtual ref<WorkResult> createWorkResult() const = 0;
/**
* Create a copy of this work processor instance.
* \brief Create a copy of this work processor instance.
*
* Note: Before the cloned work processor is used, its
* prepare() method will be called - therefore, state
* that is initialized there does not have to be copied.
@ -108,22 +106,23 @@ public:
virtual ref<WorkProcessor> clone() const = 0;
/**
* Called once before processing starts. This is useful for allocating
* scratch space or resolving references to resource objects. Lengthy
* computations should be performed in process() instead of here, since
* this this method will be called while the central scheduler lock
* is held. A thrown exception will lead to the termination of the parallel
* process.
* \brief Called once before processing starts.
*
* This is useful for allocating scratch space or resolving references
* to resource objects. Lengthy computations should be performed in
* process() instead of here, since this this method will be called
* while the central scheduler lock is held. A thrown exception will
* lead to the termination of the parallel process.
*/
virtual void prepare() = 0;
/**
* Process a work unit and store the computed results. The <tt>active</tt>
* parameter can be used to signal a premature stop of the execution flow.
* In this case, the work result is allowed to be undefined (it will
* simply be ignored).
* A thrown exception will lead to the termination of the parallel
* process.
* \brief Process a work unit and store the computed results.
*
* The <tt>active</tt> parameter can be used to signal a premature
* stop of the execution flow. In this case, the work result is allowed
* to be undefined (it will simply be ignored). A thrown exception will
* lead to the termination of the parallel process.
*/
virtual void process(const WorkUnit *workUnit, WorkResult *workResult,
const bool &stop) = 0;
@ -138,9 +137,10 @@ protected:
: SerializableObject(stream, manager) { }
/**
* Look up a named resource, which has been bound to the associated
* parallel process. Throws an exception if the resource is not
* known / bound.
* \brief Look up a named resource, which has been bound to
* the associated parallel process.
*
* Throws an exception if the resource is not known / bound.
*/
SerializableObject *getResource(const std::string &name);
protected:
@ -148,114 +148,143 @@ protected:
};
/**
* Abstract parallelizable task. Models a larger piece of work that
* can be split into independent `units' and subsequently farmed
* out over a cluster or processed locally. After the work units have
* been completed, the results are pieced back together to a solution of
* the original large-scale problem. This class implements the core logic
* running on the central scheduling server, i.e. the part that is
* responsible for generating work units and accepting their results.
* The module that performs the actual computation is an instance of
* <tt>WorkProcessor</tt>, which is also specified here.
* \brief Abstract parallelizable task.
*
* Models a larger piece of work that can be split into independent
* `units' and subsequently farmed out over a cluster or processed locally.
* After the work units have been completed, the results are pieced back
* together to a solution of the original large-scale problem. This class
* implements the core logic running on the central scheduling server,
* i.e. the part that is responsible for generating work units and
* accepting their results. The module that performs the actual computation
* is an instance of <tt>WorkProcessor</tt>, which is also specified here.
* Finally, the this class references `resources', which denote
* chunks of globally shared read-only data required during execution.
*/
class MTS_EXPORT_CORE ParallelProcess : public Object {
friend class Scheduler;
public:
/// Binding from local resource names to global resource IDs
typedef std::map<std::string, int> ResourceBindings;
/// Return codes used by generateWork() and getReturnStatus()
enum EStatus {
EUnknown,
EPause,
ESuccess,
EFailure
EUnknown, ///< Unknown return status
EPause, ///< Temporarily, no work units can be created
ESuccess, ///< The process finished / a piece of work was generated
EFailure ///< The process failed / no more work is available
};
/**
* Generate a piece of work. Takes a pre-allocated <tt>WorkUnit</tt>
* instance of the appropriate sub-type and size (as specified by
* <tt>ParallelProcess::getWorkUnitName</tt>) and fills it with the
* appropriate content. Returns ESuccess on success and EFailure or EPause
* when no more work is left -- in that case, the work unit will
* be ignored and the process completed (EFailure) or temporarily
* paused (EPause). When EPause was used, resubmission via
* <tt>Scheduler::schedule()</tt> will be required once more work
* is available. In some cases, it is useful to distribute 'nearby'
* pieces of work to the same processor -- the <tt>worker</tt>
* parameter can be used to implement this.
* This function should run as quickly as possible, since it will
* be executed while the scheduler mutex is held. A thrown exception
* will lead to the termination of the parallel process.
* \brief Generate a piece of work.
*
* Takes a pre-allocated <tt>\ref WorkUnit</tt> instance of
* the appropriate sub-type and size (as specified by
* <tt>\ref ParallelProcess::getWorkUnitName()</tt>) and
* fills it with the appropriate content. Returns ESuccess
* on success and EFailure or EPause when no more work is
* left -- in that case, the work unit will be ignored and
* the process completed (\ref EFailure) or temporarily
* paused (\ref EPause). When \ref EPause was used,
* resubmission via <tt>\ref Scheduler::schedule()</tt> will
* be required once more work is available. In some cases, it
* is useful to distribute 'nearby' pieces of work to the same
* processor -- the <tt>worker</tt> parameter can be used to
* implement this.
* This function should run as quickly as possible, since it
* will be executed while the scheduler mutex is held. A
* thrown exception will lead to the termination of the
* parallel process.
*
* \param unit Work unit data structure to be filled
* \param worker ID of the worker executing this function
*/
virtual EStatus generateWork(WorkUnit *unit, int worker) = 0;
/**
* Called whenever a work unit has been completed. Note
* that this may be executed by different threads and
* likely out of order (some sort of locking will
* generally be required when modifying data structures).
* \brief Called whenever a work unit has been completed.
*
* Note that this function may concurrently be executed by
* multiple threads. Also, processing of work results will
* generally be out of order with respect to the creation
* in \ref generateWork().
*
* When a work unit is only partially completed due to
* a call to <tt>Scheduler::cancel</tt>, the second
* parameter is set to true.
* A thrown exception will lead to the termination of
* the parallel process.
*
* \param result Work result to be processed
* \param cancelled Was the associated work unit not fully completed
*/
virtual void processResult(const WorkResult *result,
bool cancelled) = 0;
/**
* Called when the parallel process is canceled
* by Scheduler::cancel(). The default implementation
* does nothing.
* \brief Called when the parallel process is canceled by
* \ref Scheduler::cancel().
*
* The default implementation does nothing.
*/
virtual void handleCancellation();
/**
* After a process has finished excecution, its return
* status can be queried through this method.
* Returns one of <tt>Success, Failure or Unknown</tt>
* (EUnknown means that the process is either still running
* \brief Query the return status of a process after its
* execution has finished.
*
* Returns one of <tt>\ref Success, \ref Failure or \ref Unknown</tt>
* (\ref EUnknown means that the process is either still running
* or has never been scheduled).
*/
inline EStatus getReturnStatus() const { return m_returnStatus; }
/**
* Create an instance of the algorithm responsible
* \brief Create an instance of the algorithm responsible
* for executing the work units of this parallel process.
*/
virtual ref<WorkProcessor> createWorkProcessor() const = 0;
/**
* Bind a resource to this parallel process. Takes a resource
* ID as given by the scheduler and associates it with a name.
* This name can later be used by the work processor to access
* the resource data.
* \brief Bind a resource to this parallel process.
*
* Takes a resource ID as given by the scheduler and associates it
* with a name. This name can later be used by the work processor
* to access the resource data.
*
* \param name Process-specific name of the resource
* \param id Resource ID as returned by \ref Scheduler::registerResource()
* \sa WorkProcessor::getResource
*/
virtual void bindResource(const std::string &name, int id);
/**
* Is this process local, i.e. not distributed to remote
* processing nodes? The default implementation returs false.
* \brief Is this process strictly local?
*
* If a process is marked as local, it shouldn't be distributed
* to remote processing nodes? The default implementation
* returns false.
*/
virtual bool isLocal() const;
/**
* Return the log level for events associated with this process.
* \brief Return the log level for events associated with this process.
*
* By default, this is set to EDebug
*/
inline ELogLevel getLogLevel() const { return m_logLevel; }
/**
* Return a list of the bound resources
* \brief Return a list of all bound resources
*/
inline const ResourceBindings &getResourceBindings() const { return m_bindings; }
/**
* Return a list of plugins required by this parallel process.
* The default implementation just returns all plugins that are
* loaded in the current application image.
* \brief Return a list of plugins required by this parallel process.
*
* This is required so that remote machines can load the plugins before
* they accept work from this process. The default implementation just
* returns all plugins that are loaded in the current application.
*/
virtual std::vector<std::string> getRequiredPlugins();
@ -275,35 +304,40 @@ protected:
class Worker;
/**
* Centralized task scheduler implementation. Accepts parallelizable
* jobs and distributes their computational load both locally and remotely.
* This is done by associating different types of <tt>Worker</tt>s with
* the scheduler. These try to acquire work units from the scheduler,
* which are then executed on the current machine or sent to remote
* nodes over a network connection.
* \brief Centralized task scheduler implementation.
*
* Accepts parallelizable jobs and distributes their computational load
* both locally and remotely. This is done by associating different types
* of <tt>\ref Worker</tt>s with the scheduler. These try to acquire work
* units from the scheduler, which are then executed on the current machine
* or sent to remote nodes over a network connection.
*/
class MTS_EXPORT_CORE Scheduler : public Object {
friend class Worker;
public:
/**
* Schedule a parallelizable process for execution. If the
* scheduler is currently running and idle, its execution
* will begin immediately. Returns false if the process
* is already scheduled and has not yet terminated.
* \brief Schedule a parallelizable process for execution.
*
* If the scheduler is currently running and idle, its execution
* will begin immediately. Returns \a false if the process
* is already scheduled and has not yet terminated and \a true
* in any other case.
*/
bool schedule(ParallelProcess *process);
/**
* Block until the process has successfully been completed
* or canceled prematurely. Returns false if the process
* does not exist or has already finished by the time
* <tt>wait()</tt> is invoked.
* \brief Block until the process has successfully been completed
* or canceled prematurely.
*
* Returns false if the process does not exist or has already
* finished by the time <tt>\ref wait()</tt> is invoked.
*/
bool wait(const ParallelProcess *process);
/**
* Cancel the execution of a parallelizable process. Upon
* return, no more work from this process is running.
* \brief Cancel the execution of a parallelizable process.
*
* Upon return, no more work from this process is running.
* Returns false if the process does not exist (anymore).
*/
inline bool cancel(ParallelProcess *proc) {
@ -311,41 +345,48 @@ public:
}
/**
* Register a serializable resource with the scheduler. This should be
* thought of as a constant state that is shared amongst all processing
* nodes. Resources can be reused by subsequent parallel processes, and
* consequently do not have to be re-transmitted over the network. Returns
* a resource ID, which can be used to reference the associated data.
* \brief Register a serializable resource with the scheduler.
*
* A resource should be thought of as a constant state that is shared
* amongst all processing nodes. Resources can be reused by
* subsequent parallel processes, and consequently do not have to be
* re-transmitted over the network. Returns a resource ID, which can be
* used to reference the associated data.
*/
int registerResource(SerializableObject *resource);
/**
* Register a 'manifold' resource with the scheduler. Manifold means that
* in comparison to the previous method, a separate instance is provided
* for every core. An example where this is useful is to distribute
* random generator state when performing parallel Monte Carlo simulations.
* <tt>resources</tt> must be a vector whose length is equal
* to <tt>getCoreCount()</tt>.
* \brief Register a \a manifold resource with the scheduler.
* Manifold means that in comparison to the previous method, a separate
* instance is provided for every core. An example where this is useful
* is to distribute random generator state when performing parallel
* Monte Carlo simulations. <tt>resources</tt> must be a vector whose
* length is equal to <tt>\ref getCoreCount()</tt>.
*/
int registerManifoldResource(std::vector<SerializableObject *> &resources);
/**
* Increase the reference count of a previously registered resource.
* \brief Increase the reference count of a previously registered resource.
*
* The resource must be unregistered an additional time after calling
* this function.
*
* \sa unregisterResource
*/
void retainResource(int resourceID);
/**
* Unregister a resource from the scheduler (takes the previously
* created ID). Note that the resource's won't be removed
* until all processes using it have terminated)
* \brief Unregister a resource from the scheduler
*
* Note that the resource's won't be removed until all processes using
* it have terminated)
*/
void unregisterResource(int id);
/**
* Return the ID of a registered resource. Throws an exception
* if the resource cannot be found.
* \brief Return the ID of a registered resource
*
* Throws an exception if the resource cannot be found.
*/
int getResourceID(const SerializableObject *resource) const;
@ -365,15 +406,15 @@ public:
void start();
/**
* Puase the distribution of work units and shut down all running workers.
* Any currently scheduled work units are still completed. Processing can
* be resumed via <tt>start()</tt>.
* \brief Pause the distribution of work units and shut down all
* running workers.
*
* Any currently scheduled work units are still completed.
* Processing can be resumed via <tt>\ref start()</tt>.
*/
void pause();
/**
* Cancel all running processes and free memory used by resources
*/
/// Cancel all running processes and free memory used by resources
void stop();
/// Return the total number of cores exposed through this scheduler
@ -525,7 +566,7 @@ protected:
signalProcessTermination(item.proc, item.rec);
m_mutex->unlock();
}
/**
* Cancel the execution of a parallelizable process. Upon
* return, no more work from this process is running. When
@ -589,7 +630,7 @@ private:
};
/**
* Base class of all worker implementations
* \brief Base class of all worker implementations
*/
class MTS_EXPORT_CORE Worker : public Thread {
friend class Scheduler;
@ -615,20 +656,22 @@ protected:
int workerIndex, int coreOffset);
/**
* Called to inform a worker that a resource is no longer in use. The
* remote worker uses this to notify the machine on the other end that
* \brief Called to inform a worker that a resource is no longer in use.
*
* The remote worker uses this to notify the machine on the other end that
* the memory used by this resource can now be released.
*/
virtual void signalResourceExpiration(int id) = 0;
/**
* Called to inform a worker that a process has been cancelled
* \brief Called to inform a worker that a process has been cancelled
*
* Guaranteed to be called while the Scheduler's main lock is held.
*/
virtual void signalProcessCancellation(int id) = 0;
/**
* Called to inform a worker that a process has successfully been
* \brief Called to inform a worker that a process has successfully been
* completed and any associated resources can be freed.
*/
virtual void signalProcessTermination(int id) = 0;
@ -669,7 +712,7 @@ protected:
};
/**
* Local worker thread. Acquires work from the scheduler and executes
* \brief Acquires work from the scheduler and executes
* it locally.
*/
class MTS_EXPORT_CORE LocalWorker : public Worker {

View File

@ -21,11 +21,11 @@
#include <mitsuba/core/sched.h>
/* How many work units should be sent to a remote worker
/** How many work units should be sent to a remote worker
at a time? This is a multiple of the worker's core count */
#define BACKLOG_FACTOR 3
/* Once the back log factor drops below this value (also a
/** Once the back log factor drops below this value (also a
multiple of the core size), the stream processor will
continue sending batches of work units */
#define CONTINUE_FACTOR 2
@ -36,13 +36,16 @@ class RemoteWorkerReader;
class StreamBackend;
/**
* Remote worker thread. Acquires work from the scheduler and forwards
* it to a processing node reachable over some form of stream (usually
* a <tt>SocketStream</tt>).
* \brief Acquires work from the scheduler and forwards
* it to a processing node reachable through a \ref Stream.
*/
class MTS_EXPORT_CORE RemoteWorker : public Worker {
friend class RemoteWorkerReader;
public:
/**
* \brief Construct a new remote worker with the given name and
* communication stream
*/
RemoteWorker(const std::string &name, Stream *stream);
/// Return the name of the node on the other side
@ -84,8 +87,9 @@ protected:
};
/**
* Remote worker helper thread - constantly waits for finished
* work units sent by the processing node.
* \brief Communication helper thread required by \ref RemoteWorker.
*
* Constantly waits for finished work units sent by the processing node.
*/
class MTS_EXPORT_CORE RemoteWorkerReader : public Thread {
friend class RemoteWorker;
@ -110,11 +114,19 @@ private:
};
/**
* 'Fake' parallel process used to insert work units from a
* \brief Parallel process facade used to insert work units from a
* remote scheduler into the local one.
*/
class MTS_EXPORT_CORE RemoteProcess : public ParallelProcess {
public:
/**
* \brief Create a new remote process
*
* \param id Identification number for this process
* \param logLevel Log level for events associated with this process
* \param backend The responsible server-side communication backend
* \param proc Work processor instance for use with this process
*/
RemoteProcess(int id, ELogLevel logLevel,
StreamBackend *backend, WorkProcessor *proc);
@ -125,6 +137,7 @@ public:
ref<WorkProcessor> createWorkProcessor() const;
void handleCancellation();
/// Get an empty work unit from the process (or create one)
inline WorkUnit *getEmptyWorkUnit() {
ref<WorkUnit> wu;
m_mutex->lock();
@ -139,12 +152,14 @@ public:
return wu;
}
/// Make a full work unit available to the process
inline void putFullWorkUnit(WorkUnit *wu) {
m_mutex->lock();
m_full.push_back(wu);
m_mutex->unlock();
}
/// Mark the process as finished
inline void setDone() {
m_mutex->lock();
m_done = true;
@ -166,9 +181,10 @@ private:
};
/**
* Stream backend - attaches to the end of a stream, accepts work units
* and forwards them to the local scheduler. Can be used to create
* remote processing nodes.
* \brief Network processing communication backend
*
* Attaches to the end of a stream, accepts work units and forwards
* them to the local scheduler. Can be used to create network processing nodes.
*/
class MTS_EXPORT_CORE StreamBackend : public Thread {
friend class RemoteProcess;
@ -192,7 +208,7 @@ public:
};
/**
* Create a new stream backend
* \brief Create a new stream backend
*
* @param name
* Name of the created thread

View File

@ -32,10 +32,13 @@ namespace ublas = boost::numeric::ublas;
struct SHVector;
/* Stores the diagonal blocks of a spherical harmonic rotation matrix */
/**
* \brief Stores the diagonal blocks of a spherical harmonic rotation matrix
*/
struct MTS_EXPORT_CORE SHRotation {
std::vector<ublas::matrix<Float> > blocks;
/// Construct a new rotation storage for the given number of bands
inline SHRotation(int bands) : blocks(bands) {
for (int i=0; i<bands; ++i) {
int dim = 2*i+1;
@ -44,26 +47,31 @@ struct MTS_EXPORT_CORE SHRotation {
}
/**
* Transform a coefficient vector and store the result into
* the given target vector. The source and target must have
* the same number of bands.
* \brief Transform a coefficient vector and store the result into
* the given target vector.
*
* The source and target must have the same number of bands.
*/
void operator()(const SHVector &source, SHVector &target) const;
};
/**
* Stores a truncated real spherical harmonics representation of
* an L2-integrable function. Also provides some other useful
* functionality, such as evaluation, projection and rotation.
* \brief Stores a truncated real spherical harmonics representation of
* an L2-integrable function.
*
* Also provides some other useful functionality, such as evaluation,
* projection and rotation.
*
* The Mathematica equivalent of the basis functions implemented here is:
*
* <pre>
* SphericalHarmonicQ[l_, m_, \[Theta]_, \[Phi]_] :=
* Piecewise[{
* {SphericalHarmonicY[l, m, \[Theta], \[Phi]], m == 0},
* {Sqrt[2]*Re[SphericalHarmonicY[l, m, \[Theta], \[Phi]]], m > 0},
* {Sqrt[2]*Im[SphericalHarmonicY[l, -m, \[Theta], \[Phi]]], m < 0}
* }]
* </pre>
*/
struct MTS_EXPORT_CORE SHVector {
public:
@ -169,18 +177,20 @@ public:
/// Evaluate for a direction given in spherical coordinates
Float eval(Float theta, Float phi) const;
/// Evaluate for a direction given in cartesian coordinates
/// Evaluate for a direction given in Cartesian coordinates
Float eval(const Vector &v) const;
/**
* Evaluate for a direction given in spherical coordinates.
* \brief Evaluate for a direction given in spherical coordinates.
*
* This function is much faster but only works for azimuthally
* invariant functions
*/
Float evalAzimuthallyInvariant(Float theta, Float phi) const;
/**
* Evaluate for a direction given in cartesian coordinates.
* \brief Evaluate for a direction given in cartesian coordinates.
*
* This function is much faster but only works for azimuthally
* invariant functions
*/
@ -214,8 +224,10 @@ public:
void offset(Float value);
/**
* Convolve the SH representation with the supplied kernel,
* which must be rotationally symmetric around the Z-axis.
* \brief Convolve the SH representation with the supplied kernel.
*
* Based on the Funk-Hecke theorem -- the kernel must be rotationally
* symmetric around the Z-axis.
*/
void convolve(const SHVector &kernel);
@ -303,7 +315,7 @@ public:
return error/denom;
}
/* Evaluate an associated Legendre polynomial using the usual recurrence formulae */
/// Evaluate an associated Legendre polynomial using the usual recurrence formulae
static Float legendre(int l, int m, Float x);
/// Return a normalization coefficient
@ -315,8 +327,9 @@ public:
}
/**
* Recursively computes rotation matrices for each band of SH coefficients. Based on
* 'Rotation Matrices for Real Spherical Harmonics. Direct Determination by Recursion'
* \brief Recursively computes rotation matrices for each band of SH coefficients.
*
* Based on 'Rotation Matrices for Real Spherical Harmonics. Direct Determination by Recursion'
* by Ivanic and Ruedenberg. The implemented tables follow the notation in
* 'Spherical Harmonic Lighting: The Gritty Details' by Robin Green.
*/
@ -340,22 +353,23 @@ private:
};
/**
* Implementation of 'Importance Sampling Spherical Harmonics'
* \brief Implementation of 'Importance Sampling Spherical Harmonics'
* by W. Jarsz, N. Carr and H. W. Jensen (EUROGRAPHICS 2009)
*/
class MTS_EXPORT_CORE SHSampler : public Object {
public:
/**
* Create a spherical harmonics sampler object for the
* specified amount of SH coefficient bands. The 'depth'
* parameter specifies the number of recursive sample
* warping steps.
* \brief Precompute a spherical harmonics sampler object
*
* \param bands Number of SH coefficient bands to support
* \param depth Number of recursive sample warping steps.
*/
SHSampler(int bands, int depth);
/**
* Warp a uniform sample in [0,1]^2 to one that is
* \brief Warp a uniform sample in [0,1]^2 to one that is
* approximately proportional to the specified function.
*
* The resulting sample will have spherical coordinates
* [0,pi]x[0,2pi] and its actual PDF (which might be
* slightly different from the function evaluated at the
@ -370,7 +384,7 @@ public:
protected:
/// Virtual destructor
virtual ~SHSampler();
/* Index into the assoc. legendre polynomial table */
inline int I(int l, int m) const { return l*(l+1)/2 + m; }
@ -381,11 +395,11 @@ protected:
return -m_phiMap[depth][phiBlock][P(m)] * m_legendreMap[depth][zBlock][I(l, std::abs(m))];
}
/* Recursively compute assoc. legendre & phi integrals */
/// Recursively compute assoc. legendre & phi integrals
Float *legendreIntegrals(Float a, Float b);
Float *phiIntegrals(Float a, Float b);
/* Integrate a SH expansion over the specified mip-map region */
/// Integrate a SH expansion over the specified mip-map region
Float integrate(int depth, int zBlock, int phiBlock, const SHVector &f) const;
protected:
int m_bands;

View File

@ -24,10 +24,11 @@
MTS_NAMESPACE_BEGIN
/**
* Stores a 4D function f(wi, wo) (such as a BRDF or phase function)
* using a 2D table of spherical harmonics expansions. Discretizaiton
* occurs in the 'wi' space. Later lookups interpolate amongst
* the 4 adjacent samples
* \brief Stores a 4D function f(wi, wo) (such as a BRDF or phase function)
* using a 2D table of spherical harmonics expansions.
*
* Discretizaiton occurs in the 'wi' space. Lookups interpolate amongst
* the 4 adjacent samples.
*/
struct SHVector4D {
public:

View File

@ -25,14 +25,15 @@
MTS_NAMESPACE_BEGIN
/**
* Mesh vertex data structure. Stores 3D coordinates,
* vertex normals, UV coordinates and a tangent frame
* \brief Mesh vertex data structure. Stores 3D coordinates,
* vertex normals, UV coordinates and a tangent frame.
*/
struct Vertex {
Point v;
Normal n;
Point2 uv;
Vector dpdu, dpdv;
Point v; ///< %Vertex position
Normal n; ///< %Vertex normal
Point2 uv; ///< %Texture coordinates
Vector dpdu; ///< Partial derivative of the position with respect to \a u.
Vector dpdv; ///< Partial derivative of the position with respect to \a v.
inline bool operator==(const Vertex &vert) const {
return (v == vert.v && n == vert.n && uv == vert.uv
@ -44,26 +45,29 @@ struct Vertex {
}
};
/** \brief Triangle class including a collection of routines
* for analysis and transformation. Triangles are stored as
* indices into a vertex array
/**
* \brief Simple triangle class including a collection of routines
* for analysis and transformation.
*
* Triangles are stored as indices into a vertex array
*/
struct MTS_EXPORT_CORE Triangle {
/* Indices into a vertex buffer */
/// Indices into a vertex buffer
unsigned int idx[3];
/// Construct an axis-aligned box, which contains the triangle
AABB getAABB(const Vertex *buffer) const;
/**
* Returns the axis-aligned bounding box of a triangle after it has
* clipped to the extends of another, given AABB. This function uses the
* Sutherland-Hodgman algorithm to calculate the convex polygon, which
* is created when applying all 6 AABB splitting planes to the triangle.
* Afterwards, the AABB of the newly created convex polygon is returned.
* This function is an important component for efficiently creating
* 'Perfect Split' KD-trees. For more detail, see
* "On building fast kd-Trees for Ray Tracing, and on doing
* \brief Returns the axis-aligned bounding box of a triangle after it has
* clipped to the extends of another, given AABB.
*
* This function uses the Sutherland-Hodgman algorithm to calculate the
* convex polygon, which is created when applying all 6 AABB splitting
* planes to the triangle. Afterwards, the AABB of the newly created
* convex polygon is returned. This function is an important component
* for efficiently creating 'Perfect Split' KD-trees. For more detail,
* see "On building fast kd-Trees for Ray Tracing, and on doing
* that in O(N log N)" by Ingo Wald and Vlastimil Havran
*/
AABB getClippedAABB(const Vertex *buffer, const AABB &aabb) const;
@ -73,8 +77,8 @@ struct MTS_EXPORT_CORE Triangle {
* Uses the algorithm presented by Moeller and Trumbore at
* http://www.acm.org/jgt/papers/MollerTrumbore97/code.html
* Returns true if an intersection has been detected
* On success, pT contains the distance from the ray origin to the
* intersection point and pUV contains the intersection point in
* On success, \a t contains the distance from the ray origin to the
* intersection point, and \a u and \a v contain the intersection point in
* the local triangle coordinate system
*/
bool rayIntersect(const Vertex *buffer, const Ray &ray, Float &u,

View File

@ -38,19 +38,18 @@
MTS_NAMESPACE_BEGIN
class SparseWavelet2D;
class SparseWaveletOctree;
/**
* Non-standard 2D Haar wavelet transformation. Based on
* "Wavelets for computer graphics: A primer, part 1" by
* \brief Performs non-standard 2D Haar wavelet transformations.
*
* Based on "Wavelets for computer graphics: A primer, part 1" by
* Eric J. Stollnitz, Tony D. DeRose, and David H. Salesin
* (IEEE Computer Graphics and Applications, May 1995)
*/
class MTS_EXPORT_CORE Wavelet2D : public Object {
public:
/**
* Create a wavelet representation from a given bitmap.
* \brief Create a wavelet representation from a given bitmap.
*
* Only one color channel is supported for this encoding, so
* the desired channel must be selected using the `colorChannel'
* parameter.
@ -61,7 +60,8 @@ public:
Wavelet2D(const SparseWavelet2D *sw);
/**
* Turn the wavelet representation back into an image.
* \brief Turn the wavelet representation back into an image.
*
* Optionally, scale+offset factors can be supplied to
* map the bitmap to a desired brightness
*/
@ -71,7 +71,7 @@ public:
void discard(Float fraction);
/**
* Discard components such that the relative L^2-error is below the
* \brief Discard components such that the relative L^2-error is below the
* given bound. Returns the achieved compression ratio.
*/
Float compress(Float maxError);
@ -122,7 +122,8 @@ protected:
};
/**
* Implements the non-standard 3D wavelet transform using Haar basis functions.
* \brief Implements the non-standard 3D wavelet transform using
* Haar basis functions.
*/
class MTS_EXPORT_CORE Wavelet3D : public Object {
public:
@ -134,7 +135,7 @@ public:
Wavelet3D(const float *data, size_t resolution);
/**
* Turn the wavelet representation back into a dense format
* \brief Turn the wavelet representation back into a dense format
*/
void decode(float *target);
@ -142,7 +143,7 @@ public:
void discard(Float fraction);
/**
* Discard components such that the relative L^2-error is below the
* \brief Discard components such that the relative L^2-error is below the
* given bound. Returns the achieved compression ratio.
*/
Float compress(Float maxRelError);
@ -193,7 +194,7 @@ protected:
};
/**
* Sparse 2D wavelet representation using the Haar basis
* \brief Sparse 2D wavelet representation using the Haar basis
*/
class MTS_EXPORT_CORE SparseWavelet2D : public SerializableObject {
public:
@ -302,8 +303,9 @@ public:
Float getPixel(const Point2i &pt) const;
/**
* Compute a line integral in 2D wavelet space. Coordinates are
* expected as pixel coordinates in [0,0]-[size,size],
* \brief Compute a line integral in 2D wavelet space.
*
* Coordinates are expected as pixel coordinates in [0,0]-[size,size],
* but are allowed to be fractional
*/
Float lineIntegral(Point2 start, Point2 end) const;
@ -329,7 +331,8 @@ protected:
};
/**
* Sparse 3D wavelet representation using the Haar basis and an octree structure
* \brief Sparse 3D wavelet representation using the Haar basis and an
* octree structure
*/
class MTS_EXPORT_CORE SparseWaveletOctree : public Object {
public: