Path.h
Go to the documentation of this file.00001 /**<!--------------------------------------------------------------------> 00002 @class Path 00003 @author Travis Fischer (fisch0920@gmail.com) 00004 @author Matthew Jacobs (jacobs.mh@gmail.com) 00005 @date Fall 2008 00006 00007 @brief 00008 Core data structure for manipulating a sequence x0,x1,...,xk of points on 00009 scene surfaces. Paths are the central unit in the path integral formulation 00010 of light transport, upon which path tracing, bidirectional path tracing, and 00011 MLT are all founded. 00012 00013 Each Path is assumed to either start at an emitter (light subpath), end at a 00014 sensor (eye subpath), or both start at an emitter and end at a sensor 00015 (complete, valid path). 00016 <!-------------------------------------------------------------------->**/ 00017 00018 #ifndef PATH_H_ 00019 #define PATH_H_ 00020 00021 #include <renderers/utils/PathVertex.h> 00022 00023 class Renderer; 00024 00025 class Path { 00026 public: 00027 ///@name Constructors 00028 //@{----------------------------------------------------------------- 00029 00030 inline Path(const PathVertexList &vertices, Renderer *renderer) 00031 : m_vertices(vertices), m_renderer(renderer) 00032 { } 00033 00034 inline Path(Renderer *renderer) 00035 : m_renderer(renderer) 00036 { } 00037 00038 00039 //@}----------------------------------------------------------------- 00040 ///@name Functionality related to path as a whole 00041 //@{----------------------------------------------------------------- 00042 00043 /** 00044 * @returns the luminance propagated along this path in the direction 00045 * of lightflow (beginning with an emitter) 00046 */ 00047 inline real_t getContribution() const { 00048 return getRadiance().getRGB().luminance(); 00049 } 00050 00051 /** 00052 * @returns the radiance propagated along this path in the direction 00053 * of lightflow (beginning with an emitter) 00054 */ 00055 inline SpectralSampleSet getRadiance() const { 00056 if (length() > 0) 00057 return back().alphaL; 00058 00059 return SpectralSampleSet::black(); 00060 } 00061 00062 /** 00063 * @returns the unweighted contribution of this path broken up into 00064 * a light subpath prefix of length @p s and an eye subpath suffix 00065 * of length @p t 00066 * 00067 * @note this method contains an implicit visibility check between the 00068 * connecting edge which will not be performed if (s + t) is equal 00069 * to the length of this path (since this path is already assumed 00070 * to be 'valid', visibility is therefore guaranteed in this case) 00071 * @note if @p tentative is true, the aforementioned visibility check 00072 * will not be evaluated (visibility is assumed) 00073 * @note either this light subpath or the given eye subpath may be 00074 * empty, but not both (an empty path is considered invalid), 00075 * which implies that (s + t) >= 2 00076 * 00077 * @see section 10.2 (pgs 302-305) of Veach's thesis for more details 00078 */ 00079 SpectralSampleSet getContribution(unsigned s, unsigned t, 00080 bool tentative = false); 00081 00082 real_t getPdf(unsigned s, unsigned t, bool tentative = false); 00083 00084 /** 00085 * @returns an array of @p k + 1 probability densities in @p pdfs, 00086 * corresponding to all of the @p k + 1 ways in which this path with 00087 * @p k vertices could be broken up into different length light and 00088 * eye subpaths 00089 * 00090 * @param k denotes the path length of interest (k <= the length of this 00091 * path) 00092 * @param actualS denotes the length of the actual light path which this 00093 * path was generated from (actualS <= the length of this path) 00094 * @param pdfs is an out-array which is assumed to be preallocated to 00095 * hold at least @p k + 1 real_ts 00096 * 00097 * @note probability densities are with respect to a surface area measure 00098 * on the space of all paths 00099 * 00100 * @see section 10.2 (pgs 302-305) of Veach's thesis for more details 00101 */ 00102 void getPdfs(unsigned k, unsigned actualS, real_t *pdfs); 00103 00104 /** 00105 * @brief 00106 * Draws an OpenGL preview of this path by rendering edges between 00107 * adjacent vertices using a single GL_LINE_STRIP 00108 */ 00109 void preview(); 00110 00111 00112 //@}----------------------------------------------------------------- 00113 ///@name Path deletion operations 00114 //@{----------------------------------------------------------------- 00115 00116 /** 00117 * @brief 00118 * Clears this Path of all vertices, resulting in an empty path 00119 */ 00120 inline void clear() { 00121 m_vertices.clear(); 00122 } 00123 00124 /** 00125 * @returns a copy of the path formed by the left n + 1 vertices of the 00126 * form: x0,x1,...,xn 00127 * @note @p n is inclusive here 00128 */ 00129 inline Path left(unsigned n) { 00130 return Path(PathVertexList(m_vertices.begin(), m_vertices.begin() + n), 00131 m_renderer); 00132 } 00133 00134 /** 00135 * @returns a copy of the path formed by the right-most vertices 00136 * starting at the nth vertex of the form: x(n),x(n+1),...,xk 00137 * @note @p n is inclusive here 00138 */ 00139 inline Path right(unsigned n) { 00140 return Path(PathVertexList(m_vertices.begin() + n, m_vertices.end()), 00141 m_renderer); 00142 } 00143 00144 /** 00145 * @brief 00146 * Removes the back vertex (last light vertex) in this Path 00147 */ 00148 inline void pop_back() { 00149 ASSERT(length() > 0); 00150 m_vertices.pop_back(); 00151 } 00152 00153 /** 00154 * @brief 00155 * Removes the front vertex (last eye vertex) in this Path 00156 */ 00157 inline void pop_front() { 00158 ASSERT(length() > 0); 00159 m_vertices.pop_front(); 00160 } 00161 00162 00163 //@}----------------------------------------------------------------- 00164 ///@name Path addition operations 00165 //@{----------------------------------------------------------------- 00166 00167 /** 00168 * @brief 00169 * Samples the BSDF at the end of this light path, and attempts to 00170 * add a new PathVertex corresponding to the first surface intersected 00171 * in the sampled direction, updating all internal data as necessary. 00172 * 00173 * @param roulette denotes whether or not to apply standard russian 00174 * roulette to the decision of whether or not to add a vertex 00175 * 00176 * @returns whether or not a vertex was successfully added 00177 * @note may return false if no surface was found in the sampled direction 00178 * or if @p roulette is true and the random walk is terminated via 00179 * russian roulette 00180 */ 00181 bool append(bool roulette = false); 00182 00183 /** 00184 * @brief 00185 * Samples the BSDF at the end of this eye path, and attempts to 00186 * add a new PathVertex corresponding to the first surface intersected 00187 * in the sampled direction, updating all internal data as necessary. 00188 * 00189 * @param roulette denotes whether or not to apply standard russian 00190 * roulette to the decision of whether or not to add a vertex 00191 * 00192 * @returns whether or not a vertex was successfully added 00193 * @note may return false if no surface was found in the sampled direction 00194 * or if @p roulette is true and the random walk is terminated via 00195 * russian roulette 00196 */ 00197 bool prepend(bool roulette = false); 00198 00199 /** 00200 * @brief 00201 * Adds the given PathVertex at the end of this eye path 00202 * 00203 * @note only valid if the current path is empty, and 'v1' is assumed 00204 * to be on a sensor 00205 * @returns true if the point was successfully added or false if the 00206 * operation would invalidate this path 00207 */ 00208 bool prepend(const PathVertex &v1); 00209 00210 /** 00211 * @brief 00212 * Appends the given eye subpath onto this light subpath, updating 00213 * both the cumulative eye and light contributions along the way 00214 * 00215 * @note either there are no restrictions or edge cases with respect 00216 * to path lengths; either or both paths may be empty 00217 * @returns true if the resulting path is valid, false otherwise (the 00218 * resulting path will be invalid -- zero contribution -- if the 00219 * last light subpath vertex first eye subpath vertex are not 00220 * mutually visible) 00221 */ 00222 bool append (const Path &path); 00223 00224 00225 //@}----------------------------------------------------------------- 00226 ///@name PathVertex accessors 00227 //@{----------------------------------------------------------------- 00228 00229 inline PathVertex &operator[](unsigned index) { 00230 ASSERT(index < length()); 00231 00232 return m_vertices[index]; 00233 } 00234 00235 inline const PathVertex &operator[](unsigned index) const { 00236 ASSERT(index < length()); 00237 00238 return m_vertices[index]; 00239 } 00240 00241 inline PathVertex &front() { 00242 ASSERT(length() > 0); 00243 00244 return m_vertices[0]; 00245 } 00246 00247 inline const PathVertex &front() const { 00248 ASSERT(length() > 0); 00249 00250 return m_vertices[0]; 00251 } 00252 00253 inline PathVertex &back() { 00254 ASSERT(length() > 0); 00255 00256 return m_vertices[length() - 1]; 00257 } 00258 00259 inline const PathVertex &back() const { 00260 ASSERT(length() > 0); 00261 00262 return m_vertices[length() - 1]; 00263 } 00264 00265 00266 //@}----------------------------------------------------------------- 00267 ///@name Size accessors 00268 //@{----------------------------------------------------------------- 00269 00270 inline unsigned length() const { 00271 return m_vertices.size(); 00272 } 00273 00274 inline unsigned getNoVertices() const { 00275 return m_vertices.size(); 00276 } 00277 00278 inline unsigned getNoEdges() const { 00279 const unsigned noVertices = getNoVertices(); 00280 00281 return (noVertices < 2 ? 0 : noVertices - 1); 00282 } 00283 00284 00285 //@}----------------------------------------------------------------- 00286 ///@name Miscellaneous functionality 00287 //@{----------------------------------------------------------------- 00288 00289 inline Renderer *getRenderer() { 00290 return m_renderer; 00291 } 00292 00293 inline void setRenderer(Renderer *renderer) { 00294 m_renderer = renderer; 00295 } 00296 00297 std::string toHeckbertNotation() const; 00298 00299 00300 //@}----------------------------------------------------------------- 00301 00302 protected: 00303 /** 00304 * @brief 00305 * Samples the BSDF at the end of the path (which end is determined 00306 * implicitly by the adjoint parameter), and attempts to add a new 00307 * PathVertex corresponding to the first surface intersected in the 00308 * sampled direction, updating all internal data as necessary. 00309 * 00310 * @param roulette denotes whether or not to apply standard russian 00311 * roulette to the decision of whether or not to add a vertex 00312 * 00313 * @returns whether or not a vertex was successfully added 00314 * @note may return false if no surface was found in the sampled direction 00315 * or if @p roulette is true and the random walk is terminated via 00316 * russian roulette 00317 */ 00318 bool _samplePathVertex(bool roulette, bool adjoint); 00319 00320 /** 00321 * @brief 00322 * Initializes light-path vertex @p y with respect to the point given 00323 * 00324 * @param roulette denotes whether or not to apply standard russian 00325 * roulette to the decision of whether or not to add a vertex 00326 * 00327 * @note @p y and @p pt are assumed to be mutually visible to each other 00328 * @returns the updated cumulative light subpath contribution (@p alphaL) 00329 * and the updated cumulative light subpath probability density (@p pL) 00330 * and whether or not to add the vertex (if russian roulette is 00331 * disabled or succeeded) 00332 */ 00333 bool _initL(PathVertex &y, const Vector3 &wo, real_t t, SurfacePoint *pt, 00334 SpectralSampleSet &alphaL, real_t &pL, bool roulette = false) const; 00335 00336 /** 00337 * @brief 00338 * Initializes eye-path vertex @p z with respect to the point given 00339 * 00340 * @param roulette denotes whether or not to apply standard russian 00341 * roulette to the decision of whether or not to add a vertex 00342 * 00343 * @note @p z and @p pt are assumed to be mutually visible to each other 00344 * @returns the updated cumulative eye subpath contribution (@p alphaE) 00345 * and the updated cumulative eye subpath probability density (@p pE) 00346 * and whether or not to add the vertex (if russian roulette is 00347 * disabled or succeeded) 00348 */ 00349 bool _initE(PathVertex &z, const Vector3 &wo, real_t t, SurfacePoint *pt, 00350 SpectralSampleSet &alphaE, real_t &pE, bool roulette = false) const; 00351 00352 protected: 00353 PathVertexList m_vertices; 00354 Renderer *m_renderer; 00355 }; 00356 00357 /// Prints a Path to an output stream 00358 std::ostream &operator<<(std::ostream &os, const Path &path); 00359 00360 #endif // PATH_H_ 00361
Generated on 28 Feb 2009 for Milton by
1.5.6