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// The version can reliably be found in this header file from OpenEXR,
57// for both 2.x and 3.x:
58#include <OpenEXR/OpenEXRConfig.h>
59#define COMBINED_OPENEXR_VERSION ((10000*OPENEXR_VERSION_MAJOR) + \
60 (100*OPENEXR_VERSION_MINOR) + \
61 OPENEXR_VERSION_PATCH)
62
63// There's just no easy way to have an `#include` that works in both
64// cases, so we use the version to switch which set of include files we
65// use.
66#if COMBINED_OPENEXR_VERSION >= 20599 /* 2.5.99: pre-3.0 */
67# include <Imath/ImathFun.h>
68# include <Imath/ImathMatrix.h>
69#else
70 // OpenEXR 2.x, use the old locations
71# include <OpenEXR/ImathFun.h>
72# include <OpenEXR/ImathMatrix.h>
73#endif
74
75
76//----------------------------------------------------------------------------//
77
78#include "ns.h"
79
81
82//----------------------------------------------------------------------------//
83// Curve
84//----------------------------------------------------------------------------//
85
92//----------------------------------------------------------------------------//
93
94template <typename T>
95class Curve
96{
97public:
98
99 // Typedefs ------------------------------------------------------------------
100
101 typedef std::pair<float, T> Sample;
102 typedef std::vector<Sample> SampleVec;
103
104 // Main methods --------------------------------------------------------------
105
109 void addSample(const float t, const T &value);
110
113 T linear(const float t) const;
114
116 size_t numSamples() const
117 { return m_samples.size(); }
118
120 const SampleVec& samples() const
121 { return m_samples; }
122
124 void clear()
125 { SampleVec().swap(m_samples); }
126
127private:
128
129 // Structs -------------------------------------------------------------------
130
133 public std::unary_function<std::pair<float, T>, bool>
134 {
136 : m_match(match)
137 { }
138 bool operator()(std::pair<float, T> test)
139 {
140 return test.first > m_match;
141 }
142 private:
143 float m_match;
144 };
145
147 struct CheckTEqual :
148 public std::unary_function<std::pair<float, T>, bool>
149 {
151 : m_match(match)
152 { }
153 bool operator()(std::pair<float, T> test)
154 {
155 return test.first == m_match;
156 }
157 private:
158 float m_match;
159 };
160
161 // Utility methods -----------------------------------------------------------
162
168 { return T(0); }
169
173 T lerp(const Sample &lower, const Sample &upper, const float t) const
174 { return Imath::lerp(lower.second, upper.second, t); }
175
176 // Private data members ------------------------------------------------------
177
181
182};
183
184//----------------------------------------------------------------------------//
185// Template implementations
186//----------------------------------------------------------------------------//
187
188template <typename T>
189void Curve<T>::addSample(const float t, const T &value)
190{
191 using namespace std;
192 // Check that sample time is not already in curve
193 typename SampleVec::iterator i =
194 find_if(m_samples.begin(), m_samples.end(), CheckTEqual(t));
195 if (i != m_samples.end()) {
196 // Sample position already exists, so we replace it
197 i->second = value;
198 return;
199 }
200 // Find the first sample location that is greater than the interpolation
201 // position
202 i = find_if(m_samples.begin(), m_samples.end(), CheckTGreaterThan(t));
203 // If we get something other than end() back then we insert the new
204 // sample before that. If there wasn't a larger value we add this sample
205 // to the end of the vector.
206 if (i != m_samples.end()) {
207 m_samples.insert(i, make_pair(t, value));
208 } else {
209 m_samples.push_back(make_pair(t, value));
210 }
211}
212
213//----------------------------------------------------------------------------//
214
215template <typename T>
216T Curve<T>::linear(const float t) const
217{
218 using namespace std;
219 // If there are no samples, return zero
220 if (m_samples.size() == 0) {
221 return defaultReturnValue();
222 }
223 // Find the first sample location that is greater than the interpolation
224 // position
225 typename SampleVec::const_iterator i =
226 find_if(m_samples.begin(), m_samples.end(), CheckTGreaterThan(t));
227 // If we get end() back then there was no sample larger, so we return the
228 // last value. If we got the first value then there is only one value and
229 // we return that.
230 if (i == m_samples.end()) {
231 return m_samples.back().second;
232 } else if (i == m_samples.begin()) {
233 return m_samples.front().second;
234 }
235 // Interpolate between the nearest two samples.
236 const Sample &upper = *i;
237 const Sample &lower = *(--i);
238 const float interpT = Imath::lerpfactor(t, lower.first, upper.first);
239 return lerp(lower, upper, interpT);
240}
241
242//----------------------------------------------------------------------------//
243// Template specializations
244//----------------------------------------------------------------------------//
245
246template <>
247inline Imath::Matrix44<float>
248Curve<Imath::Matrix44<float> >::defaultReturnValue() const
249{
250 Imath::Matrix44<float> identity;
251 identity.makeIdentity();
252 return identity;
253}
254
255//----------------------------------------------------------------------------//
256
257template <>
258inline Imath::Matrix44<double>
259Curve<Imath::Matrix44<double> >::defaultReturnValue() const
260{
261 Imath::Matrix44<double> identity;
262 identity.makeIdentity();
263 return identity;
264}
265
266//----------------------------------------------------------------------------//
267
269
270//----------------------------------------------------------------------------//
271
272#endif // Include guard
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.
Implements a simple function curve where samples of type T can be added along a 1D axis....
Definition Curve.h:96
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:173
SampleVec m_samples
Stores the samples that define the curve. Sample insertion ensures that the samples are sorted accord...
Definition Curve.h:180
void addSample(const float t, const T &value)
Adds a sample point to the curve.
Definition Curve.h:189
size_t numSamples() const
Returns the number of samples in the curve.
Definition Curve.h:116
const SampleVec & samples() const
Returns a const reference to the samples in the curve.
Definition Curve.h:120
std::pair< float, T > Sample
Definition Curve.h:101
T defaultReturnValue() const
The default return value is used when no sample points are available. This defaults to zero,...
Definition Curve.h:167
void clear()
Clears all samples in curve.
Definition Curve.h:124
T linear(const float t) const
Linearly interpolates a value from the curve.
Definition Curve.h:216
std::vector< Sample > SampleVec
Definition Curve.h:102
#define FIELD3D_NAMESPACE_HEADER_CLOSE
Definition ns.h:58
Used when finding values in the m_samples vector.
Definition Curve.h:149
bool operator()(std::pair< float, T > test)
Definition Curve.h:153
CheckTEqual(float match)
Definition Curve.h:150
Used when finding values in the m_samples vector.
Definition Curve.h:134
CheckTGreaterThan(float match)
Definition Curve.h:135
bool operator()(std::pair< float, T > test)
Definition Curve.h:138