Field3D
Curve.h
Go to the documentation of this file.
1 //----------------------------------------------------------------------------//
2 
3 /*
4  * Copyright (c) 2009 Sony Pictures Imageworks Inc
5  *
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the
17  * distribution. Neither the name of Sony Pictures Imageworks nor the
18  * names of its contributors may be used to endorse or promote
19  * products derived from this software without specific prior written
20  * permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33  * OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 //----------------------------------------------------------------------------//
37 
43 //----------------------------------------------------------------------------//
44 
45 #ifndef _INCLUDED_Field3D_Curve_H_
46 #define _INCLUDED_Field3D_Curve_H_
47 
48 //----------------------------------------------------------------------------//
49 
50 #include <algorithm>
51 #include <utility>
52 #include <vector>
53 
54 #include <boost/lexical_cast.hpp>
55 
56 #include <OpenEXR/ImathFun.h>
57 #include <OpenEXR/ImathMatrix.h>
58 
59 //----------------------------------------------------------------------------//
60 
61 #include "ns.h"
62 
64 
65 //----------------------------------------------------------------------------//
66 // Curve
67 //----------------------------------------------------------------------------//
68 
75 //----------------------------------------------------------------------------//
76 
77 template <typename T>
78 class Curve
79 {
80 public:
81 
82  // Typedefs ------------------------------------------------------------------
83 
84  typedef std::pair<float, T> Sample;
85  typedef std::vector<Sample> SampleVec;
86 
87  // Main methods --------------------------------------------------------------
88 
92  void addSample(const float t, const T &value);
93 
96  T linear(const float t) const;
97 
99  size_t numSamples() const
100  { return m_samples.size(); }
101 
103  const SampleVec& samples() const
104  { return m_samples; }
105 
107  void clear()
108  { SampleVec().swap(m_samples); }
109 
110 private:
111 
112  // Structs -------------------------------------------------------------------
113 
116  public std::unary_function<std::pair<float, T>, bool>
117  {
119  : m_match(match)
120  { }
121  bool operator()(std::pair<float, T> test)
122  {
123  return test.first > m_match;
124  }
125  private:
126  float m_match;
127  };
128 
130  struct CheckTEqual :
131  public std::unary_function<std::pair<float, T>, bool>
132  {
134  : m_match(match)
135  { }
136  bool operator()(std::pair<float, T> test)
137  {
138  return test.first == m_match;
139  }
140  private:
141  float m_match;
142  };
143 
144  // Utility methods -----------------------------------------------------------
145 
151  { return T(0); }
152 
156  T lerp(const Sample &lower, const Sample &upper, const float t) const
157  { return Imath::lerp(lower.second, upper.second, t); }
158 
159  // Private data members ------------------------------------------------------
160 
164 
165 };
166 
167 //----------------------------------------------------------------------------//
168 // Template implementations
169 //----------------------------------------------------------------------------//
170 
171 template <typename T>
172 void Curve<T>::addSample(const float t, const T &value)
173 {
174  using namespace std;
175  // Check that sample time is not already in curve
176  typename SampleVec::iterator i =
177  find_if(m_samples.begin(), m_samples.end(), CheckTEqual(t));
178  if (i != m_samples.end()) {
179  // Sample position already exists, so we replace it
180  i->second = value;
181  return;
182  }
183  // Find the first sample location that is greater than the interpolation
184  // position
185  i = find_if(m_samples.begin(), m_samples.end(), CheckTGreaterThan(t));
186  // If we get something other than end() back then we insert the new
187  // sample before that. If there wasn't a larger value we add this sample
188  // to the end of the vector.
189  if (i != m_samples.end()) {
190  m_samples.insert(i, make_pair(t, value));
191  } else {
192  m_samples.push_back(make_pair(t, value));
193  }
194 }
195 
196 //----------------------------------------------------------------------------//
197 
198 template <typename T>
199 T Curve<T>::linear(const float t) const
200 {
201  using namespace std;
202  // If there are no samples, return zero
203  if (m_samples.size() == 0) {
204  return defaultReturnValue();
205  }
206  // Find the first sample location that is greater than the interpolation
207  // position
208  typename SampleVec::const_iterator i =
209  find_if(m_samples.begin(), m_samples.end(), CheckTGreaterThan(t));
210  // If we get end() back then there was no sample larger, so we return the
211  // last value. If we got the first value then there is only one value and
212  // we return that.
213  if (i == m_samples.end()) {
214  return m_samples.back().second;
215  } else if (i == m_samples.begin()) {
216  return m_samples.front().second;
217  }
218  // Interpolate between the nearest two samples.
219  const Sample &upper = *i;
220  const Sample &lower = *(--i);
221  const float interpT = Imath::lerpfactor(t, lower.first, upper.first);
222  return lerp(lower, upper, interpT);
223 }
224 
225 //----------------------------------------------------------------------------//
226 // Template specializations
227 //----------------------------------------------------------------------------//
228 
229 template <>
230 inline Imath::Matrix44<float>
231 Curve<Imath::Matrix44<float> >::defaultReturnValue() const
232 {
233  Imath::Matrix44<float> identity;
234  identity.makeIdentity();
235  return identity;
236 }
237 
238 //----------------------------------------------------------------------------//
239 
240 template <>
241 inline Imath::Matrix44<double>
242 Curve<Imath::Matrix44<double> >::defaultReturnValue() const
243 {
244  Imath::Matrix44<double> identity;
245  identity.makeIdentity();
246  return identity;
247 }
248 
249 //----------------------------------------------------------------------------//
250 
252 
253 //----------------------------------------------------------------------------//
254 
255 #endif // Include guard
FIELD3D_NAMESPACE_HEADER_CLOSE
#define FIELD3D_NAMESPACE_HEADER_CLOSE
Definition: ns.h:58
Curve::CheckTEqual::operator()
bool operator()(std::pair< float, T > test)
Definition: Curve.h:136
Curve::numSamples
size_t numSamples() const
Returns the number of samples in the curve.
Definition: Curve.h:99
Curve::CheckTGreaterThan
Used when finding values in the m_samples vector.
Definition: Curve.h:115
Curve::m_samples
SampleVec m_samples
Stores the samples that define the curve. Sample insertion ensures that the samples are sorted accord...
Definition: Curve.h:163
Curve::Sample
std::pair< float, T > Sample
Definition: Curve.h:84
Curve
Implements a simple function curve where samples of type T can be added along a 1D axis....
Definition: Curve.h:78
Curve::addSample
void addSample(const float t, const T &value)
Adds a sample point to the curve.
Definition: Curve.h:172
ns.h
Curve::samples
const SampleVec & samples() const
Returns a const reference to the samples in the curve.
Definition: Curve.h:103
match
bool match(const std::string &name, const std::string &attribute, const std::vector< std::string > &patterns, const MatchFlags flags=MatchEmptyPattern)
Matches a <name>:<attribute> string against a set of patterns.
Definition: PatternMatch.cpp:102
Curve::lerp
T lerp(const Sample &lower, const Sample &upper, const float t) const
The default implementation for linear interpolation. Works for all classes for which Imath::lerp is i...
Definition: Curve.h:156
Curve::CheckTGreaterThan::m_match
float m_match
Definition: Curve.h:126
Curve::CheckTEqual::CheckTEqual
CheckTEqual(float match)
Definition: Curve.h:133
Curve::SampleVec
std::vector< Sample > SampleVec
Definition: Curve.h:85
Curve::CheckTGreaterThan::CheckTGreaterThan
CheckTGreaterThan(float match)
Definition: Curve.h:118
Curve::CheckTEqual::m_match
float m_match
Definition: Curve.h:141
Curve::CheckTGreaterThan::operator()
bool operator()(std::pair< float, T > test)
Definition: Curve.h:121
FIELD3D_NAMESPACE_OPEN
Definition: FieldMapping.cpp:74
Curve::defaultReturnValue
T defaultReturnValue() const
The default return value is used when no sample points are available. This defaults to zero,...
Definition: Curve.h:150
Curve::CheckTEqual
Used when finding values in the m_samples vector.
Definition: Curve.h:130
Curve::clear
void clear()
Clears all samples in curve.
Definition: Curve.h:107
Curve::linear
T linear(const float t) const
Linearly interpolates a value from the curve.
Definition: Curve.h:199