From 6433604064e3fbea3e55804865bfd42510fcddd4 Mon Sep 17 00:00:00 2001 From: Wenzel Jakob Date: Sun, 31 Oct 2010 16:06:26 +0100 Subject: [PATCH] documentation updates --- doc/development.tex | 97 ++++++++++++++++++++++++++++++++ doc/integrator.tex | 4 +- doc/main.tex | 1 + doc/parallelization.tex | 2 +- include/mitsuba/render/sampler.h | 29 ++++++++-- 5 files changed, 127 insertions(+), 6 deletions(-) create mode 100644 doc/development.tex diff --git a/doc/development.tex b/doc/development.tex new file mode 100644 index 00000000..e2462eb0 --- /dev/null +++ b/doc/development.tex @@ -0,0 +1,97 @@ +\section{Development Guide} +This chapter and the subsequent ones will provide an overview +of the the coding conventions and general architecture of Mitsuba. +You should only read them if if you wish to interface with the API +in some way (e.g. by developing your own plugins). The coding style +section is only relevant if you plan to submit patches, which should +go into the main codebase. + +\subsection{Coding style} +\paragraph{Indentation:} The Mitsuba codebase uses tabs for indentation, +which expand to \emph{four} spaces. Please make sure that you configure your editor +this way, otherwise the source code layout will look garbled. + +\paragraph{Placement of braces:} Opening braces should be placed on the +same line to make the best use of vertical space, i.e. +\begin{cpp} +if (x > y) { + x = y; +} +\end{cpp} + +\paragraph{Placement of spaces:} Placement of spaces follows K\&R, e.g. +\begin{cpp} +if (x == y) { + .. +} else if (x > y) { + .. +} else { + .. +} +\end{cpp} +rather than things like this +\begin{cpp} +if ( x==y ){ +} +.. +\end{cpp} + +\paragraph{Name format:} Names are always written in camel-case. +Classes and structures start with a capital letter, whereas member functions +and attributes start with a lower-case letter. Attributes of classes +have the prefix \code{m\_}. Here is an example: +\begin{cpp} +class MyClass { +public: + MyClass(int value) : m_value(value) { } + + inline void setValue(int value) { m_value = value; } + inline int getValue() const { return m_value; } +private: + int m_value; +}; +\end{cpp} + +\paragraph{Enumerations:} For clarity, both enumerations types and entries +start with a capital \textbf{E}, e.g. +\begin{cpp} +enum ETristate { + ENo = 0, + EYes, + EMaybe +}; +\end{cpp} +\paragraph{Constant methods and parameters:} Declare member functions and +their parameters as \code{const} whenever this is possible +and properly conveys the semantics. +\paragraph{Inline methods:} Always inline trivial pieces of code, such +as getters and setters. +\paragraph{Documentation:} Headers files should contain +Doxygen-compatible documentation. It is also a good idea to add +comments to a \code{.cpp} file to explain subtleties of an implemented algorithm. +However, anything pertaining to the API should go into the header file. + +\paragraph{Boost:} Use the boost libraries whenever this helps to save +time or write more compact code. + +\paragraph{Classes vs structures:}In Mitsuba, classes \emph{always} go onto the heap, +whereas structures may be allocated both on the stack and the heap. + +Classes that derive from \code{Object} usually implement a protected virtual +deconstructor, which explicitly prevents them from being allocated on the stack. +The only way they can be deallocated is using the built-in reference +counting. This is done using the \code{ref<>} template, e.g. + +\begin{cpp} +if (..) { + ref instance = new MyClass(); + instance->doSomething() +} // reference expires, instance will be deallocated +\end{cpp} + +\paragraph{Separation of plugins:}Mitsuba encourages that plugins are only +used via the generic interface they implement. You will find that almost all plugins +(e.g. luminaires) don't actually provide a header file, hence they can only be accessed +using the generic \code{Luminaire} interface they implement. If any kind of special +interaction between plugins is needed, this is usually an indication that the +generic interface should be extended to accomodate this. diff --git a/doc/integrator.tex b/doc/integrator.tex index ec5f8115..5ef7fe73 100644 --- a/doc/integrator.tex +++ b/doc/integrator.tex @@ -128,7 +128,9 @@ which automatically perform endianness translation. In our case, the so we don't really have to do anything. Note that it is crucial that your code calls the serialization and unserialization -implementations of the superclass! +implementations of the superclass, since it will also read/write some +information to the stream. + We haven't used the \texttt{manager} parameter yet, so here is a quick overview of what it does: if many cases, we don't just want to serialize a single class, but a whole graph of objects. Some may be referenced many diff --git a/doc/main.tex b/doc/main.tex index 07e9a6ce..e49a5411 100644 --- a/doc/main.tex +++ b/doc/main.tex @@ -113,6 +113,7 @@ \include{format} \include{plugins} \include{import} +\include{development} \include{integrator} \include{parallelization} \include{acknowledgements} diff --git a/doc/parallelization.tex b/doc/parallelization.tex index 1e83ea35..3498cbb3 100644 --- a/doc/parallelization.tex +++ b/doc/parallelization.tex @@ -221,7 +221,7 @@ are rather trivial. Note the \code{stop} field in the \code{process} method. This field is used to abort running jobs at the users requests, hence it is a good idea to periodically check its value during lengthy computations. -Finally, we need a called \emph{parallel process} +Finally, we need a so-called \emph{parallel process} instance, which is responsible for creating work units and stitching work results back into a solution of the whole problem. The \code{ROT13} implementation might look as follows: diff --git a/include/mitsuba/render/sampler.h b/include/mitsuba/render/sampler.h index 3d3cedea..99be3d5c 100644 --- a/include/mitsuba/render/sampler.h +++ b/include/mitsuba/render/sampler.h @@ -26,10 +26,26 @@ MTS_NAMESPACE_BEGIN /** - * Abstract sample generator. Generates a high-dimensional sample - * and provides 1D and 2D pieces of it to the integrator as requested. - * An implementation will ideally provide a sequence that is well - * laid-out in sample space using either stratification or QMC techniques. + * \brief Base class of all sample generators. + * + * For each sample in a pixel, a sample generator produces a (hypothetical) + * point in the infinite dimensional random number cube. A rendering + * algorithm can then request subsequent 1D or 2D components of this point + * using the \ref next1D() and \ref next2D() functions. Some implementations + * make certain guarantees about the stratification of the first n components + * with respect to the other pixel samples. (the low-discrepancy and + * stratified samplers do this for instance). + * + * The general interaction between a sampler and a rendering algorithm is as + * follows: Before beginning to render a pixel, the rendering algorithm calls + * \ref generate(). The first pixel sample is generated, after which \ref + * advance() needs to be invoked, and so on. Note that any implementations need + * to be configured for a certain number of pixel samples, and exceeding these + * will lead to an exception being thrown. While computing a pixel sample, the + * rendering algorithm usually requests batches of (pseudo-) random numbers + * using the \ref next1D(), \ref next2D(), \ref next1DArray() and + * \ref next2DArray() functions. + * */ class MTS_EXPORT_RENDER Sampler : public ConfigurableObject { public: @@ -70,6 +86,11 @@ public: * requested initially using request2DArray and later, they have * to be retrieved in the same same order and size configuration as the * requests. An exception is thrown when a mismatch is detected. + * + * This function is useful to support things such as a direct illumination + * rendering technique with "n" pixel samples and "m" shading samples, + * while ensuring that the "n*m" sampled positions on an area light source + * are all well-stratified with respect to each other. */ Point2 *next2DArray(unsigned int size);