Mitsuba Renderer  0.5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
trimesh.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_TRIMESH_H_)
21 #define __MITSUBA_RENDER_TRIMESH_H_
22 
23 #include <mitsuba/core/triangle.h>
24 #include <mitsuba/core/pmf.h>
25 #include <mitsuba/render/shape.h>
26 
28 
29 /**
30  * \brief Simple tangent space storage for surfaces
31  *
32  * Note that the \ref dpdu and \ref dpdv vectors are not
33  * necessarily orthogonal.
34  *
35  * \ingroup librender
36  * \ingroup libpython
37  */
38 struct TangentSpace {
39  /// Position partial with respect to the U parameter of the local chart
41 
42  /// Position partial with respect to the V parameter of the local chart
44 
45  inline TangentSpace() { }
46  inline TangentSpace(const Vector &dpdu, const Vector &dpdv)
47  : dpdu(dpdu), dpdv(dpdv) { }
48  inline TangentSpace(Stream *stream) :
49  dpdu(stream), dpdv(stream) {
50  }
51 
52  inline void serialize(Stream *stream) {
53  dpdu.serialize(stream);
54  dpdv.serialize(stream);
55  }
56 
57  inline std::string toString() const {
58  std::ostringstream oss;
59  oss << "TangentSpace[dpdu=" << dpdu.toString() << ", dpdv=" << dpdv.toString() << "]";
60  return oss.str();
61  }
62 };
63 
64 /** \brief Abstract triangle mesh base class
65  * \ingroup librender
66  * \ingroup libpython
67  */
69 public:
70  /// Create a new, empty triangle mesh with the specified state
71  TriMesh(const std::string &name,
72  size_t triangleCount, size_t vertexCount,
73  bool hasNormals = false,
74  bool hasTexcoords = false,
75  bool hasVertexColors = false,
76  bool flipNormals = false,
77  bool faceNormals = false);
78 
79  /// Unserialize a triangle mesh
80  TriMesh(Stream *stream, InstanceManager *manager);
81 
82  /**
83  * \brief Unserialize a triangle mesh
84  *
85  * This is an alternative routine, which only loads triangle data
86  * (no BSDF, Sub-surface integrator, etc.) in a format that will
87  * remain stable as Mitsuba evolves. The files can optionally contain
88  * multiple meshes -- in that case, the specified index determines
89  * which one to load.
90  */
91  TriMesh(Stream *stream, int idx = 0);
92 
93  // =============================================================
94  //! @{ \name General query functions
95  // =============================================================
96 
97  /// Return the total surface area
98  Float getSurfaceArea() const;
99 
100  /// Return a bounding box containing the mesh
101  AABB getAABB() const;
102 
103  /// Return a bounding box containing the mesh
104  inline AABB &getAABB() { return m_aabb; }
105 
106  /**
107  * \brief Create a triangle mesh approximation of this shape
108  *
109  * Since instances are already triangle meshes, the implementation
110  * just returns a pointer to \a this.
111  */
113 
114  //! @}
115  // =============================================================
116 
117  // =============================================================
118  //! @{ \name Access to the stored triangle mesh
119  // =============================================================
120 
121  /// Return the number of triangles
122  inline size_t getTriangleCount() const { return m_triangleCount; }
123  /// Return the number of vertices
124  inline size_t getVertexCount() const { return m_vertexCount; }
125 
126  /// Return the triangle list (const version)
127  inline const Triangle *getTriangles() const { return m_triangles; };
128  /// Return the triangle list
129  inline Triangle *getTriangles() { return m_triangles; };
130 
131  /// Return the vertex positions (const version)
132  inline const Point *getVertexPositions() const { return m_positions; };
133  /// Return the vertex positions
134  inline Point *getVertexPositions() { return m_positions; };
135 
136  /// Return the vertex normals (const version)
137  inline const Normal *getVertexNormals() const { return m_normals; };
138  /// Return the vertex normals
139  inline Normal *getVertexNormals() { return m_normals; };
140  /// Does the mesh have vertex normals?
141  inline bool hasVertexNormals() const { return m_normals != NULL; };
142 
143  /// Return the vertex colors (const version)
144  inline const Color3 *getVertexColors() const { return m_colors; };
145  /// Return the vertex colors
146  inline Color3 *getVertexColors() { return m_colors; };
147  /// Does the mesh have vertex colors?
148  inline bool hasVertexColors() const { return m_colors != NULL; };
149 
150  /// Return the vertex texture coordinates (const version)
151  inline const Point2 *getVertexTexcoords() const { return m_texcoords; };
152  /// Return the vertex texture coordinates
153  inline Point2 *getVertexTexcoords() { return m_texcoords; };
154  /// Does the mesh have vertex texture coordinates?
155  inline bool hasVertexTexcoords() const { return m_texcoords != NULL; };
156 
157  /// Return the per-triangle UV tangents (const version)
158  inline const TangentSpace *getUVTangents() const { return m_tangents; };
159  /// Return the per-triangle UV tangents
160  inline TangentSpace *getUVTangents() { return m_tangents; };
161  /// Does the mesh have UV tangent information?
162  inline bool hasUVTangents() const { return m_tangents != NULL; };
163 
164  //! @}
165  // =============================================================
166 
167  // =============================================================
168  //! @{ \name Sampling routines
169  // =============================================================
170 
171  /**
172  * \brief Sample a point on the surface of this shape instance
173  * (with respect to the area measure)
174  *
175  * The returned sample density will be uniform over the surface.
176  *
177  * \param pRec
178  * A position record, which will be used to return the sampled
179  * position, as well as auxilary information about the sample.
180  *
181  * \param sample
182  * A uniformly distributed 2D vector
183  */
185  const Point2 &sample) const;
186 
187  /**
188  * \brief Query the probability density of \ref samplePosition() for
189  * a particular point on the surface.
190  *
191  * This method will generally return the inverse of the surface area.
192  *
193  * \param pRec
194  * A position record, which will be used to return the sampled
195  * position, as well as auxilary information about the sample.
196  */
197 
198  Float pdfPosition(const PositionSamplingRecord &pRec) const;
199 
200  //! @}
201  // =============================================================
202 
203  // =============================================================
204  //! @{ \name Miscellaneous
205  // =============================================================
206 
207  /**
208  * \brief Generate per-triangle space basis vectors from
209  * a user-specified set of UV coordinates
210  *
211  * Will throw an exception when no UV coordinates are
212  * associated with the mesh.
213  */
214  void computeUVTangents();
215 
216  /**
217  * \brief Generate smooth vertex normals?
218  *
219  * \param force
220  * When this parameter is set to true, the function
221  * generates normals <em>even</em> when there are
222  * already existing ones.
223  */
224  void computeNormals(bool force = false);
225 
226  /**
227  * \brief Rebuild the mesh so that adjacent faces
228  * with a dihedral angle greater than \c maxAngle degrees
229  * are topologically disconnected.
230  *
231  * On the other hand, if the angle is less than \a maxAngle, the code
232  * ensures that the faces reference the same vertices.
233  * This step is very useful as a pre-process when generating
234  * high-quality smooth shading normals on meshes with creases.
235  * Note: this function is fairly memory intensive and will require
236  * approximately three 3x the storate used by the input mesh.
237  * It will never try to merge vertices with equal positions but
238  * different UV coordinates or vertex colors.
239  */
240  void rebuildTopology(Float maxAngle);
241 
242  /// Serialize to a file/network stream
243  void serialize(Stream *stream, InstanceManager *manager) const;
244 
245  /**
246  * \brief Serialize to a file/network stream
247  *
248  * This is an alternative routine, which \a only loads triangle
249  * data (no BSDF, Sub-surface integrator, etc.) in a format that
250  * will remain stable as Mitsuba evolves.
251  */
252  void serialize(Stream *stream) const;
253 
254  /**
255  * \brief Build a discrete probability distribution
256  * for sampling.
257  *
258  * Called once while loading the scene
259  */
260  virtual void configure();
261 
262  /**
263  * \brief Return the derivative of the normal vector with
264  * respect to the UV parameterization
265  *
266  * This can be used to compute Gaussian and principal curvatures,
267  * amongst other things.
268  *
269  * \param its
270  * Intersection record associated with the query
271  * \param dndu
272  * Parameter used to store the partial derivative of the
273  * normal vector with respect to \c u
274  * \param dndv
275  * Parameter used to store the partial derivative of the
276  * normal vector with respect to \c v
277  * \param shadingFrame
278  * Specifies whether to compute the derivative of the
279  * geometric or shading normal of the surface
280  */
281  void getNormalDerivative(const Intersection &its,
282  Vector &dndu, Vector &dndv, bool shadingFrame) const;
283 
284  /**
285  * \brief Return the number of primitives (triangles, hairs, ..)
286  * contributed to the scene by this shape
287  *
288  * Does not include instanced geometry
289  */
290  size_t getPrimitiveCount() const;
291 
292  /**
293  * \brief Return the number of primitives (triangles, hairs, ..)
294  * contributed to the scene by this shape
295  *
296  * Includes instanced geometry
297  */
298  size_t getEffectivePrimitiveCount() const;
299 
300  /// Import a shape from the Blender in-memory representation
301  static ref<TriMesh> fromBlender(const std::string &name, size_t faceCount, void *facePtr,
302  size_t vertexCount, void *vertexPtr, void *uvPtr, void *colPtr, short matNr);
303 
304  /// Export a Wavefront OBJ version of this file
305  void writeOBJ(const fs::path &path) const;
306 
307  /// Export a Stanford PLY version of this file
308  void writePLY(const fs::path &path) const;
309 
310  /// Return a string representation
311  std::string toString() const;
312 
313  //! @}
314  // =============================================================
315 
317 protected:
318  /// Create a new triangle mesh
319  TriMesh(const Properties &props);
320 
321  /// Virtual destructor
322  virtual ~TriMesh();
323 
324  /// Load a Mitsuba compressed triangle mesh substream
325  void loadCompressed(Stream *stream, int idx = 0);
326 
327  /**
328  * \brief Reads the header information of a compressed file, returning
329  * the version ID.
330  *
331  * This function assumes the stream is at the beginning of the compressed
332  * file and leaves the stream located right after the header.
333  */
334  static short readHeader(Stream *stream);
335 
336  /**
337  * \brief Read the idx-th entry from the offset diccionary at the end of
338  * the stream, which has to be open already, given the file version tag.
339  * This function modifies the position of the stream.
340  */
341  static size_t readOffset(Stream *stream, short version, int idx);
342 
343  /**
344  * \brief Read the entirety of the end-of-file offset dictionary from the
345  * already open stream, replacing the contents of the input vector.
346  * If the file is not large enough the function returns -1
347  * and does not modify the vector.
348  * This function modifies the position of the stream.
349  */
350  static int readOffsetDictionary(Stream *stream, short version,
351  std::vector<size_t>& outOffsets);
352 
353  /// Prepare internal tables for sampling uniformly wrt. area
354  void prepareSamplingTable();
355 protected:
356  AABB m_aabb;
357  Triangle *m_triangles;
358  Point *m_positions;
359  Normal *m_normals;
360  Point2 *m_texcoords;
361  TangentSpace *m_tangents;
362  Color3 *m_colors;
363  size_t m_triangleCount;
364  size_t m_vertexCount;
365  bool m_flipNormals;
366  bool m_faceNormals;
367 
368  /* Surface and distribution -- generated on demand */
369  DiscreteDistribution m_areaDistr;
370  Float m_surfaceArea;
371  Float m_invSurfaceArea;
372  ref<Mutex> m_mutex;
373 };
374 
376 
377 #endif /* __MITSUBA_RENDER_TRIMESH_H_ */
virtual ref< TriMesh > createTriMesh()
Create a triangle mesh approximation of this shape.
Color3 * getVertexColors()
Return the vertex colors.
Definition: trimesh.h:146
Three-dimensional normal data structure.
Definition: normal.h:39
Abstract triangle mesh base class.
Definition: trimesh.h:68
virtual void serialize(Stream *stream, InstanceManager *manager) const
Serialize this shape to a stream.
Simple triangle class including a collection of routines for analysis and transformation.
Definition: triangle.h:35
virtual size_t getPrimitiveCount() const =0
Return the number of primitives (triangles, hairs, ..) contributed to the scene by this shape...
Point2 * getVertexTexcoords()
Return the vertex texture coordinates.
Definition: trimesh.h:153
Vector dpdu
Position partial with respect to the U parameter of the local chart.
Definition: trimesh.h:40
virtual AABB getAABB() const =0
Return a bounding box containing the shape.
Generic sampling record for positions.
Definition: common.h:82
size_t getVertexCount() const
Return the number of vertices.
Definition: trimesh.h:124
TangentSpace * getUVTangents()
Return the per-triangle UV tangents.
Definition: trimesh.h:160
const Normal * getVertexNormals() const
Return the vertex normals (const version)
Definition: trimesh.h:137
Triangle * getTriangles()
Return the triangle list.
Definition: trimesh.h:129
#define MTS_NAMESPACE_BEGIN
Definition: platform.h:137
const Point2 * getVertexTexcoords() const
Return the vertex texture coordinates (const version)
Definition: trimesh.h:151
TangentSpace(Stream *stream)
Definition: trimesh.h:48
TangentSpace()
Definition: trimesh.h:45
size_t getTriangleCount() const
Return the number of triangles.
Definition: trimesh.h:122
Abstract base class of all shapes.
Definition: shape.h:178
const Triangle * getTriangles() const
Return the triangle list (const version)
Definition: trimesh.h:127
RGB color data type.
Definition: spectrum.h:612
Point * getVertexPositions()
Return the vertex positions.
Definition: trimesh.h:134
const TangentSpace * getUVTangents() const
Return the per-triangle UV tangents (const version)
Definition: trimesh.h:158
void serialize(Stream *stream)
Definition: trimesh.h:52
Axis-aligned bounding box data structure in three dimensions.
Definition: aabb.h:437
virtual void getNormalDerivative(const Intersection &its, Vector &dndu, Vector &dndv, bool shadingFrame=true) const
Return the derivative of the normal vector with respect to the UV parameterization.
virtual void configure()
Called once after constructing the object.
bool hasVertexTexcoords() const
Does the mesh have vertex texture coordinates?
Definition: trimesh.h:155
virtual void samplePosition(PositionSamplingRecord &pRec, const Point2 &sample) const
Sample a point on the surface of this shape instance (with respect to the area measure) ...
Simple tangent space storage for surfaces.
Definition: trimesh.h:38
virtual Float getSurfaceArea() const
Return the shape&#39;s surface area.
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
virtual Float pdfPosition(const PositionSamplingRecord &pRec) const
Query the probability density of samplePosition() for a particular point on the surface.
Definition: fwd.h:99
Reference counting helper.
Definition: ref.h:40
bool hasVertexColors() const
Does the mesh have vertex colors?
Definition: trimesh.h:148
const Color3 * getVertexColors() const
Return the vertex colors (const version)
Definition: trimesh.h:144
bool hasVertexNormals() const
Does the mesh have vertex normals?
Definition: trimesh.h:141
std::string toString() const
Definition: trimesh.h:57
Definition: fwd.h:96
virtual size_t getEffectivePrimitiveCount() const =0
Return the number of primitives (triangles, hairs, ..) contributed to the scene by this shape...
const Point * getVertexPositions() const
Return the vertex positions (const version)
Definition: trimesh.h:132
Normal * getVertexNormals()
Return the vertex normals.
Definition: trimesh.h:139
bool hasUVTangents() const
Does the mesh have UV tangent information?
Definition: trimesh.h:162
TangentSpace(const Vector &dpdu, const Vector &dpdv)
Definition: trimesh.h:46
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
Vector dpdv
Position partial with respect to the V parameter of the local chart.
Definition: trimesh.h:43
Definition: fwd.h:100
Coordinates the serialization and unserialization of object graphs.
Definition: serialization.h:65
#define MTS_EXPORT_RENDER
Definition: platform.h:109
AABB & getAABB()
Return a bounding box containing the mesh.
Definition: trimesh.h:104
virtual std::string toString() const
Return a human-readable string representation of the object&#39;s contents.
#define MTS_NAMESPACE_END
Definition: platform.h:138
Thin wrapper around the recursive boost thread lock.
Definition: lock.h:34
Discrete probability distribution.
Definition: pmf.h:35