Mitsuba Renderer  0.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
shape.h
Go to the documentation of this file.
1 /*
2  This file is part of Mitsuba, a physically based rendering system.
3 
4  Copyright (c) 2007-2014 by Wenzel Jakob and others.
5 
6  Mitsuba is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License Version 3
8  as published by the Free Software Foundation.
9 
10  Mitsuba is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #pragma once
20 #if !defined(__MITSUBA_RENDER_SHAPE_H_)
21 #define __MITSUBA_RENDER_SHAPE_H_
22 
23 #include <mitsuba/render/common.h>
24 #include <mitsuba/core/cobject.h>
25 #include <mitsuba/core/transform.h>
26 #include <mitsuba/core/frame.h>
27 #include <mitsuba/core/aabb.h>
28 
30 
31 /** \brief Container for all information related to
32  * a surface intersection
33  * \ingroup librender
34  * \ingroup libpython
35  */
37 public:
38  inline Intersection() :
39  shape(NULL), t(std::numeric_limits<Float>::infinity()) { }
40 
41  /// Convert a local shading-space vector into world space
42  inline Vector toWorld(const Vector &v) const {
43  return shFrame.toWorld(v);
44  }
45 
46  /// Convert a world-space vector into local shading coordinates
47  inline Vector toLocal(const Vector &v) const {
48  return shFrame.toLocal(v);
49  }
50 
51  /// Is the current intersection valid?
52  inline bool isValid() const {
53  return t != std::numeric_limits<Float>::infinity();
54  }
55 
56  /// Is the intersected shape also a emitter?
57  inline bool isEmitter() const;
58 
59  /// Is the intersected shape also a sensor?
60  inline bool isSensor() const;
61 
62  /// Does the intersected shape have a subsurface integrator?
63  inline bool hasSubsurface() const;
64 
65  /// Does the surface mark a transition between two media?
66  inline bool isMediumTransition() const;
67 
68  /**
69  * \brief Determine the target medium
70  *
71  * When \c isMediumTransition() = \c true, determine the medium that
72  * contains the ray (\c this->p, \c d)
73  */
74  inline const Medium *getTargetMedium(const Vector &d) const;
75 
76  /**
77  * \brief Determine the target medium based on the cosine
78  * of the angle between the geometric normal and a direction
79  *
80  * Returns the exterior medium when \c cosTheta > 0 and
81  * the interior medium when \c cosTheta <= 0.
82  */
83  inline const Medium *getTargetMedium(Float cosTheta) const;
84 
85  /**
86  * \brief Returns the BSDF of the intersected shape.
87  *
88  * The parameter ray must match the one used to create the intersection
89  * record. This function computes texture coordinate partials if this is
90  * required by the BSDF (e.g. for texture filtering).
91  *
92  * \remark This function should only be called if there is a valid
93  * intersection!
94  */
95  inline const BSDF *getBSDF(const RayDifferential &ray);
96 
97  /// Returns the BSDF of the intersected shape
98  inline const BSDF *getBSDF() const;
99 
100  /**
101  * \brief Returns radiance emitted into direction d.
102  *
103  * \remark This function should only be called if the
104  * intersected shape is actually an emitter.
105  */
106  inline Spectrum Le(const Vector &d) const;
107 
108  /**
109  * \brief Returns radiance from a subsurface integrator
110  * emitted into direction d.
111  *
112  * \remark Should only be called if the intersected
113  * shape is actually a subsurface integrator.
114  */
115  inline Spectrum LoSub(const Scene *scene, Sampler *sampler,
116  const Vector &d, int depth=0) const;
117 
118  /// Computes texture coordinate partials
119  void computePartials(const RayDifferential &ray);
120 
121  /// Move the intersection forward or backward through time
122  inline void adjustTime(Float time);
123 
124  /// Calls the suitable implementation of \ref Shape::getNormalDerivative()
125  inline void getNormalDerivative(Vector &dndu, Vector &dndv,
126  bool shadingFrame = true) const;
127 
128  /// Return a string representation
129  std::string toString() const;
130 public:
131  /// Pointer to the associated shape
132  const Shape *shape;
133 
134  /// Distance traveled along the ray
136 
137  /* Intersection point in 3D coordinates */
139 
140  /// Geometry frame
142 
143  /// Shading frame
145 
146  /// UV surface coordinates
148 
149  /// Position partials wrt. the UV parameterization
150  Vector dpdu, dpdv;
151 
152  /// UV partials wrt. changes in screen-space
153  Float dudx, dudy, dvdx, dvdy;
154 
155  /// Time value associated with the intersection
157 
158  /// Interpolated vertex color
160 
161  /// Incident direction in the local shading frame
163 
164  /// Have texture coordinate partials been computed
165  bool hasUVPartials : 1;
166 
167  /// Primitive index, e.g. the triangle ID (if applicable)
168  uint32_t primIndex : 31;
169 
170  /// Stores a pointer to the parent instance, if applicable
171  const Shape *instance;
172 };
173 
174 /** \brief Abstract base class of all shapes
175  * \ingroup librender
176  * \ingroup libpython
177  */
179 public:
180  // =============================================================
181  //! @{ \name Query functions to be implemented in subclasses
182  // =============================================================
183 
184  /// Return the name of this shape (e.g. the filename)
185  virtual std::string getName() const;
186 
187  /// Is this a compound shape consisting of several sub-objects?
188  virtual bool isCompound() const;
189 
190  /**
191  * \brief Return a sub-element of a compound shape.
192  *
193  * When expanding shapes, the scene will repeatedly call this
194  * function with increasing indices. Returning \a NULL indicates
195  * that no more elements are available.
196  */
197  virtual Shape *getElement(int i);
198 
199  /**
200  * \brief Return the shape's surface area
201  *
202  * Assumes that the object is not undergoing some kind of
203  * time-dependent scaling.
204  *
205  * The default implementation throws an exception
206  */
207  virtual Float getSurfaceArea() const;
208 
209  /// Return a bounding box containing the shape
210  virtual AABB getAABB() const = 0;
211 
212  /**
213  * \brief Returns the minimal axis-aligned bounding box
214  * of this shape when clipped to another bounding box.
215  *
216  * This is extremely important to construct decent kd-trees.
217  * The default implementation just takes the bounding box
218  * returned by \ref getAABB() and clips it to \a box.
219  */
220  virtual AABB getClippedAABB(const AABB &box) const;
221 
222  /**
223  * \brief Create a triangle mesh approximation of this shape
224  *
225  * This function is used by the realtime preview and
226  * certain integrators, which rely on hardware rasterization.
227  *
228  * The default implementation simply returns \a NULL.
229  */
230  virtual ref<TriMesh> createTriMesh();
231 
232  //! @}
233  // =============================================================
234 
235  // =============================================================
236  //! @{ \name Ray tracing routines
237  // =============================================================
238 
239  /**
240  * \brief Fast ray intersection test
241  *
242  * Check whether the shape is intersected by the given ray. Some
243  * temporary space (\ref MTS_KD_INTERSECTION_TEMP-4 bytes) is,
244  * supplied which can be used to cache information about the
245  * intersection. The function \ref fillIntersectionRecord()
246  * can later use this information to fill in a detailed
247  * intersection record.
248  *
249  * \remark In Python, this function also calls \c fillIntersectionRecord
250  * and has the signature
251  * <tt>intersection = shape.rayIntersect(ray, mint, maxt)</tt>
252  */
253  virtual bool rayIntersect(const Ray &ray, Float mint,
254  Float maxt, Float &t, void *temp) const;
255 
256  /**
257  * \brief Fast ray intersection test for visibility queries
258  *
259  * Check whether the shape is intersected by the given ray.
260  * No details about the intersection are returned, hence the
261  * function is only useful for visibility queries. For most
262  * shapes, this will simply call forward the call to \ref
263  * rayIntersect. When the shape actually contains a nested
264  * kd-tree, some optimizations are possible.
265  *
266  * \remark This function is not exposed in Python
267  */
268  virtual bool rayIntersect(const Ray &ray, Float mint, Float maxt) const;
269 
270  /**
271  * \brief Given that an intersection has been found, create a
272  * detailed intersection record
273  *
274  * \remark This function is not directly exposed in Python.
275  * It is implicitly called as part of \c rayIntersect.
276  */
277  virtual void fillIntersectionRecord(const Ray &ray,
278  const void *temp, Intersection &its) const;
279 
280  /**
281  * \brief Return the derivative of the normal vector with
282  * respect to the UV parameterization
283  *
284  * This can be used to compute Gaussian and principal curvatures,
285  * amongst other things.
286  *
287  * \param its
288  * Intersection record associated with the query
289  * \param dndu
290  * Parameter used to store the partial derivative of the
291  * normal vector with respect to \c u
292  * \param dndv
293  * Parameter used to store the partial derivative of the
294  * normal vector with respect to \c v
295  * \param shadingFrame
296  * Specifies whether to compute the derivative of the
297  * geometric normal \a or the shading normal of the surface
298  *
299  * \remark In Python, the signature of this function is
300  * <tt>dndu, dndv = shape.getNormalDerivative(its, shadingFrame)</tt>
301  */
302  virtual void getNormalDerivative(const Intersection &its,
303  Vector &dndu, Vector &dndv, bool shadingFrame = true) const;
304 
305  /**
306  * \brief Compute the Gaussian and mean curvature at the given
307  * surface intersection.
308  *
309  * \param its
310  * Intersection record associated with the query
311  * \param H
312  * Parameter used to store the mean curvature
313  * \param K
314  * Parameter used to store the Gaussian curvature
315  * \param shadingFrame
316  * Specifies whether to compute the curvature based on the
317  * geometric normal \a or the shading normal of the surface
318  *
319  * \remark In Python, the signature of this function is
320  * <tt>H, K = shape.getCurvature(its, shadingFrame)</tt>
321  */
322  void getCurvature(const Intersection &its, Float &H, Float &K,
323  bool shadingFrame = true) const;
324 
325  /**
326  * Adjust an intersection record to a different time value
327  */
328  virtual void adjustTime(Intersection &its, Float time) const;
329 
330  /**
331  * \brief Return the internal kd-tree of this shape (if any)
332  *
333  * This function is used by the kd-tree visualization in
334  * the interactive walkthrough. The default implementation
335  * simply returns NULL.
336  *
337  * \remark This function is not exposed in Python
338  */
339  virtual const KDTreeBase<AABB> *getKDTree() const;
340 
341  //! @}
342  // =============================================================
343 
344  // =============================================================
345  //! @{ \name Sampling routines
346  // =============================================================
347 
348  /**
349  * \brief Sample a point on the surface of this shape instance
350  * (with respect to the area measure)
351  *
352  * The returned sample density will be uniform over the surface.
353  *
354  * \param pRec
355  * A position record, which will be used to return the sampled
356  * position, as well as auxilary information about the sample.
357  *
358  * \param sample
359  * A uniformly distributed 2D vector
360  */
361  virtual void samplePosition(PositionSamplingRecord &pRec,
362  const Point2 &sample) const;
363 
364  /**
365  * \brief Query the probability density of \ref samplePosition() for
366  * a particular point on the surface.
367  *
368  * This method will generally return the inverse of the surface area.
369  *
370  * \param pRec
371  * A position record, which will be used to return the sampled
372  * position, as well as auxilary information about the sample.
373  */
374 
375  virtual Float pdfPosition(const PositionSamplingRecord &pRec) const;
376 
377  /**
378  * \brief Sample a point on the surface of this shape instance
379  * (with respect to the solid angle measure)
380  *
381  * The sample density should ideally be uniform in direction as seen from
382  * the reference point \c dRec.p.
383  *
384  * This general approach for sampling positions is named "direct" sampling
385  * throughout Mitsuba motivated by direct illumination rendering techniques,
386  * which represent the most important application.
387  *
388  * When no implementation of this function is supplied, the \ref Shape
389  * class will revert to the default approach, which piggybacks on
390  * \ref sampleArea(). This usually results in a a suboptimal sample
391  * placement, which can manifest itself in the form of high variance
392  *
393  * \param dRec
394  * A direct sampling record that specifies the reference point and a
395  * time value. After the function terminates, it will be populated
396  * with the position sample and related information
397  *
398  * \param sample
399  * A uniformly distributed 2D vector
400  */
401  virtual void sampleDirect(DirectSamplingRecord &dRec,
402  const Point2 &sample) const;
403 
404  /**
405  * \brief Query the probability density of \ref sampleDirect() for
406  * a particular point on the surface.
407  *
408  * \param dRec
409  * A direct sampling record, which specifies the query
410  * location. Note that this record need not be completely
411  * filled out. The important fields are \c p, \c n, \c ref,
412  * \c dist, \c d, \c measure, and \c uv.
413  *
414  * \param p
415  * An arbitrary point used to define the solid angle measure
416  */
417  virtual Float pdfDirect(const DirectSamplingRecord &dRec) const;
418 
419  //! @}
420  // =============================================================
421 
422  // =============================================================
423  //! @{ \name Miscellaneous
424  // =============================================================
425 
426  /// Does the surface of this shape mark a medium transition?
427  inline bool isMediumTransition() const { return m_interiorMedium.get() || m_exteriorMedium.get(); }
428  /// Return the medium that lies on the interior of this shape (\c NULL == vacuum)
429  inline Medium *getInteriorMedium() { return m_interiorMedium; }
430  /// Return the medium that lies on the interior of this shape (\c NULL == vacuum, const version)
431  inline const Medium *getInteriorMedium() const { return m_interiorMedium.get(); }
432  /// Return the medium that lies on the exterior of this shape (\c NULL == vacuum)
433  inline Medium *getExteriorMedium() { return m_exteriorMedium; }
434  /// Return the medium that lies on the exterior of this shape (\c NULL == vacuum, const version)
435  inline const Medium *getExteriorMedium() const { return m_exteriorMedium.get(); }
436 
437  /// Does this shape have a sub-surface integrator?
438  inline bool hasSubsurface() const { return m_subsurface.get() != NULL; }
439  /// Return the associated sub-surface integrator
440  inline Subsurface *getSubsurface() { return m_subsurface; }
441  /// Return the associated sub-surface integrator
442  inline const Subsurface *getSubsurface() const { return m_subsurface.get(); }
443 
444  /// Is this shape also an area emitter?
445  inline bool isEmitter() const { return m_emitter.get() != NULL; }
446  /// Return the associated emitter (if any)
447  inline Emitter *getEmitter() { return m_emitter; }
448  /// Return the associated emitter (if any)
449  inline const Emitter *getEmitter() const { return m_emitter.get(); }
450  /// Set the emitter of this shape
451  inline void setEmitter(Emitter *emitter) { m_emitter = emitter; }
452 
453  /// Is this shape also an area sensor?
454  inline bool isSensor() const { return m_sensor.get() != NULL; }
455  /// Return the associated sensor (if any)
456  inline Sensor *getSensor() { return m_sensor; }
457  /// Return the associated sensor (if any)
458  inline const Sensor *getSensor() const { return m_sensor.get(); }
459 
460  /// Does the shape have a BSDF?
461  inline bool hasBSDF() const { return m_bsdf.get() != NULL; }
462  /// Return the shape's BSDF
463  inline const BSDF *getBSDF() const { return m_bsdf.get(); }
464  /// Return the shape's BSDF
465  inline BSDF *getBSDF() { return m_bsdf.get(); }
466  /// Set the BSDF of this shape
467  inline void setBSDF(BSDF *bsdf) { m_bsdf = bsdf; }
468 
469  /**
470  * \brief Return the number of primitives (triangles, hairs, ..)
471  * contributed to the scene by this shape
472  *
473  * Does not include instanced geometry
474  */
475  virtual size_t getPrimitiveCount() const = 0;
476 
477  /**
478  * \brief Return the number of primitives (triangles, hairs, ..)
479  * contributed to the scene by this shape
480  *
481  * Includes instanced geometry
482  */
483  virtual size_t getEffectivePrimitiveCount() const = 0;
484 
485  /// Copy attachments (BSDF, Emitter, ..) from another shape
486  void copyAttachments(Shape *shape);
487 
488  //! @}
489  // =============================================================
490 
491  // =============================================================
492  //! @{ \name ConfigurableObject interface
493  // =============================================================
494 
495  /// Called once after constructing the object
496  virtual void configure();
497 
498  /// Serialize this shape to a stream
499  virtual void serialize(Stream *stream, InstanceManager *manager) const;
500 
501  /// Add a child (e.g. a emitter/sub surface integrator) to this shape
502  void addChild(const std::string &name, ConfigurableObject *child);
503 
504  /// Add an unnamed child
505  inline void addChild(ConfigurableObject *child) { addChild("", child); }
506 
507  //! @}
508  // =============================================================
509 
511 protected:
512  /// Create a new shape
513  Shape(const Properties &props);
514 
515  /// Unserialize a shape
516  Shape(Stream *stream, InstanceManager *manager);
517 
518  /// Virtual destructor
519  virtual ~Shape();
520 protected:
521  std::string m_name;
522  ref<BSDF> m_bsdf;
523  ref<Subsurface> m_subsurface;
524  ref<Emitter> m_emitter;
525  ref<Sensor> m_sensor;
526  ref<Medium> m_interiorMedium;
527  ref<Medium> m_exteriorMedium;
528 };
529 
531 
532 #endif /* __MITSUBA_RENDER_SHAPE_H_ */
533 
534 
const Shape * shape
Pointer to the associated shape.
Definition: shape.h:132
Record for solid-angle based area sampling techniques.
Definition: common.h:238
Abstract participating medium.
Definition: medium.h:103
Subsurface * getSubsurface()
Return the associated sub-surface integrator.
Definition: shape.h:440
Stores a three-dimensional orthonormal coordinate frame.
Definition: frame.h:37
Abstract radiance emitter interface.
Definition: emitter.h:443
Generic serializable object, which supports construction from a Properties instance.
Definition: cobject.h:40
Medium * getInteriorMedium()
Return the medium that lies on the interior of this shape (NULL == vacuum)
Definition: shape.h:429
const Emitter * getEmitter() const
Return the associated emitter (if any)
Definition: shape.h:449
Generic sampling record for positions.
Definition: common.h:82
bool isMediumTransition() const
Does the surface of this shape mark a medium transition?
Definition: shape.h:427
void addChild(ConfigurableObject *child)
Add an unnamed child.
Definition: shape.h:505
const Medium * getInteriorMedium() const
Return the medium that lies on the interior of this shape (NULL == vacuum, const version) ...
Definition: shape.h:431
Principal scene data structure.
Definition: scene.h:49
Vector dpdv
Definition: shape.h:150
Abstract sensor interface.
Definition: sensor.h:66
Point2 uv
UV surface coordinates.
Definition: shape.h:147
Base class of all sample generators.
Definition: sampler.h:66
void setEmitter(Emitter *emitter)
Set the emitter of this shape.
Definition: shape.h:451
BSDF * getBSDF()
Return the shape&#39;s BSDF.
Definition: shape.h:465
bool isValid() const
Is the current intersection valid?
Definition: shape.h:52
#define MTS_NAMESPACE_BEGIN
Definition: platform.h:137
const Subsurface * getSubsurface() const
Return the associated sub-surface integrator.
Definition: shape.h:442
const Medium * getExteriorMedium() const
Return the medium that lies on the exterior of this shape (NULL == vacuum, const version) ...
Definition: shape.h:435
Abstract base class of all shapes.
Definition: shape.h:178
virtual void serialize(Stream *stream, InstanceManager *manager) const
Serialize this object to a binary data stream.
Ray differential – enhances the basic ray class with information about the rays of adjacent pixels on...
Definition: ray.h:140
bool isSensor() const
Is this shape also an area sensor?
Definition: shape.h:454
const Shape * instance
Stores a pointer to the parent instance, if applicable.
Definition: shape.h:171
Vector toLocal(const Vector &v) const
Convert a world-space vector into local shading coordinates.
Definition: shape.h:47
Vector toWorld(const Vector &v) const
Convert a local shading-space vector into world space.
Definition: shape.h:42
Axis-aligned bounding box data structure in three dimensions.
Definition: aabb.h:437
Vector wi
Incident direction in the local shading frame.
Definition: shape.h:162
virtual void addChild(const std::string &name, ConfigurableObject *child)
Add a child (default implementation throws an error)
bool isEmitter() const
Is this shape also an area emitter?
Definition: shape.h:445
Abstract seekable stream class.
Definition: stream.h:58
#define MTS_DECLARE_CLASS()
This macro must be used in the initial definition in classes that derive from Object.
Definition: class.h:158
Definition: fwd.h:99
const BSDF * getBSDF() const
Return the shape&#39;s BSDF.
Definition: shape.h:463
virtual void configure()
Configure the object (called once after construction and addition of all child ConfigurableObject ins...
Reference counting helper.
Definition: ref.h:40
const Sensor * getSensor() const
Return the associated sensor (if any)
Definition: shape.h:458
Abstract BSDF base-class.
Definition: bsdf.h:215
Definition: fwd.h:65
Definition: fwd.h:96
Medium * getExteriorMedium()
Return the medium that lies on the exterior of this shape (NULL == vacuum)
Definition: shape.h:433
Frame shFrame
Shading frame.
Definition: shape.h:144
Float time
Time value associated with the intersection.
Definition: shape.h:156
bool hasBSDF() const
Does the shape have a BSDF?
Definition: shape.h:461
Sensor * getSensor()
Return the associated sensor (if any)
Definition: shape.h:456
Spectrum color
Interpolated vertex color.
Definition: shape.h:159
Float t
Distance traveled along the ray.
Definition: shape.h:135
Associative parameter map for constructing subclasses of ConfigurableObject.
Definition: properties.h:46
Container for all information related to a surface intersection.
Definition: shape.h:36
Definition: fwd.h:100
Intersection()
Definition: shape.h:38
Coordinates the serialization and unserialization of object graphs.
Definition: serialization.h:65
Frame geoFrame
Geometry frame.
Definition: shape.h:141
#define MTS_EXPORT_RENDER
Definition: platform.h:109
Discrete spectral power distribution based on a number of wavelength bins over the 360-830 nm range...
Definition: spectrum.h:663
void setBSDF(BSDF *bsdf)
Set the BSDF of this shape.
Definition: shape.h:467
Point p
Definition: shape.h:138
bool hasSubsurface() const
Does this shape have a sub-surface integrator?
Definition: shape.h:438
Float dvdy
Definition: shape.h:153
Emitter * getEmitter()
Return the associated emitter (if any)
Definition: shape.h:447
Abstract subsurface scattering models.
Definition: subsurface.h:38
#define MTS_NAMESPACE_END
Definition: platform.h:138