00001 #ifndef _GRAPHIC_ELEM_H_
00002 #define _GRAPHIC_ELEM_H_
00003
00004 #include "fv_float.h"
00005 #include "defs.h"
00006 #include "MathHelper.h"
00007 #include "Interval.hpp"
00008 #include "Color.h"
00009
00010
00011
00012 #include <vector>
00013 #include <map>
00014 #include <string.h>
00015
00016 namespace FemViewer {
00017 using fvmath::Interval;
00018 typedef enum {
00019 eDensity,
00020 eRed,
00021 eGreen,
00022 eBlue
00023 } tf_chanel_t;
00024
00025 class TransferFunction
00026 {
00027 public:
00028 TransferFunction() {}
00029
00030 void Init() {
00031 memset(this,0x0,sizeof(*this));
00032 }
00033 #define SET(start,length) \
00034 begin = start; \
00035 end = start + (length-1); \
00036 count = length; break
00037
00038 void GetBreakpointsForChannel(tf_chanel_t channel, ScalarValueType*& begin, ScalarValueType*& end, int& count) const
00039 {
00040 switch(channel)
00041 {
00042 case eDensity:
00043 SET(m_dbrks_ptr,m_numd_bkrs);
00044 case eRed:
00045 SET(m_rbrks_ptr,m_numr_brks);
00046 case eGreen:
00047 SET(m_gbrks_ptr,m_numb_brks);
00048 case eBlue:
00049 SET(m_bbrks_ptr,m_numb_brks);
00050 default:
00051 SET(m_dbrks_ptr,m_numd_bkrs);
00052 }
00053 }
00054
00055 void GetValuesForChannel(tf_chanel_t channel, ScalarValueType*& begin, ScalarValueType*& end, int& count) const
00056 {
00057 switch(channel)
00058 {
00059 case eDensity:
00060 SET(m_dvals_ptr,m_numd_bkrs);
00061 case eRed:
00062 SET(m_rvals_ptr,m_numr_brks);
00063 case eGreen:
00064 SET(m_gbrks_ptr,m_numb_brks);
00065 case eBlue:
00066 SET(m_bbrks_ptr,m_numb_brks);
00067 default:
00068 SET(m_dbrks_ptr,m_numd_bkrs);
00069 }
00070 }
00071
00072 #undef SET
00073
00074 bool ColorContainsAtLeastOneBreakpoint(const Interval<ScalarValueType>& range) const
00075 {
00076 return RangeContainsAtLeastOneBreakpoint(eGreen, range) ||
00077 RangeContainsAtLeastOneBreakpoint(eRed, range) ||
00078 RangeContainsAtLeastOneBreakpoint(eBlue, range);
00079 }
00080
00081 bool RangeContainsAtLeastOneBreakpoint(tf_chanel_t channel, const Interval<ScalarValueType>& range) const
00082 {
00083 ScalarValueType* breakpointStart = 0;
00084 ScalarValueType* breakpointEnd = 0;
00085 int numBreakpoints = 0;
00086 GetBreakpointsForChannel(channel, breakpointStart, breakpointEnd, numBreakpoints);
00087
00088 for(int i = 0; i < numBreakpoints; ++i)
00089 {
00090 if( range.Contains(breakpointStart[i]) )
00091 {
00092 return true;
00093 }
00094 }
00095
00096 return false;
00097 }
00098
00099 bool IntersectsRange(tf_chanel_t channel, const Interval<ScalarValueType>& range) const
00100 {
00101 ScalarValueType* brs_ptr = nullptr;
00102 ScalarValueType* bre_ptr = nullptr;
00103 int count = 0;
00104 GetBreakpointsForChannel(channel, brs_ptr, bre_ptr, count);
00105
00106 return (*bre_ptr) >= range.GetLow() && (*brs_ptr) <= range.GetHigh();
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 Interval<ScalarValueType> Sample(tf_chanel_t channel, const Interval<ScalarValueType>& range) const
00220 {
00221 Interval<ScalarValueType> result;
00222 ScalarValueType left = Sample(channel, range.GetLow());
00223 ScalarValueType right = Sample(channel, range.GetHigh());
00224 result.Set(fv_min(left, right), fv_max(left, right));
00225
00226 ScalarValueType* brs_ptr = nullptr;
00227 ScalarValueType* bre_ptr = nullptr;
00228 int numBreakpoints = 0;
00229 GetBreakpointsForChannel(channel, brs_ptr, bre_ptr, numBreakpoints);
00230 ScalarValueType* vals_ptr = nullptr;
00231 ScalarValueType* vale_ptr = nullptr;
00232 int count = 0;
00233 GetValuesForChannel(channel, vals_ptr, vals_ptr, count);
00234
00235 for(int i = 0; i < numBreakpoints; ++i)
00236 {
00237 if( range.Contains(brs_ptr[i]) )
00238 {
00239 result.SetLow(fv_min(result.GetLow(), vals_ptr[i]));
00240 result.SetHigh(fv_max(result.GetHigh(), vals_ptr[i]));
00241 }
00242 }
00243 return result;
00244 }
00245
00246 ScalarValueType Sample(tf_chanel_t channel, const ScalarValueType& s) const
00247 {
00248 ScalarValueType* brs_ptr = nullptr;
00249 ScalarValueType* bre_ptr = nullptr;
00250 int numBreakpoints = 0;
00251 GetBreakpointsForChannel(channel, brs_ptr, bre_ptr, numBreakpoints);
00252
00253
00254 int index = 0;
00255 for(int i = 0; i < numBreakpoints-1; ++i)
00256 {
00257 bool test = s >= brs_ptr[i];
00258 test &= (s < brs_ptr[i+1]);
00259
00260 if (test) index = i+1;
00261 }
00262
00263 if( s >= brs_ptr[numBreakpoints-1] )
00264 {
00265 index = numBreakpoints;
00266 }
00267
00268 ScalarValueType* vals_ptr = nullptr;
00269 ScalarValueType* vale_ptr = nullptr;
00270 int count = 0;
00271 GetValuesForChannel(channel, vals_ptr, vale_ptr, count);
00272
00273 ScalarValueType result = FLOAT_CONVERT(0.0);
00274 if( index == 0 )
00275 {
00276 result = vals_ptr[0];
00277 }
00278 else if( index == numBreakpoints )
00279 {
00280 result = vals_ptr[index-1];
00281 }
00282 else
00283 {
00284 ScalarValueType v0 = vals_ptr[index-1];
00285 ScalarValueType v1 = vals_ptr[index];
00286
00287 ScalarValueType s0 = brs_ptr[index-1];
00288 ScalarValueType s1 = brs_ptr[index];
00289
00290 if( v0 == v1 )
00291 {
00292 result = v0;
00293 }
00294 else
00295 {
00296 ScalarValueType scale = FLOAT_CONVERT(1.0)/(s1-s0);
00297 result = scale*v1*(s-s0) + scale*v0*(s1-s);
00298 }
00299 }
00300
00301 return result;
00302 }
00303
00304 ScalarValueType3 SampleColor(const ScalarValueType& s) const
00305 {
00306 ScalarValueType3 result;
00307 result.x = Sample(eRed, s);
00308 result.y = Sample(eGreen, s);
00309 result.z = Sample(eBlue, s);
00310
00311 return result;
00312 }
00313
00314 ScalarValueType GetMaxValue(tf_chanel_t channel) const
00315 {
00316 ScalarValueType* begin = 0;
00317 ScalarValueType* end = 0;
00318 int count = 0;
00319 GetValuesForChannel(channel, begin, end, count);
00320 ScalarValueType result = FLOAT_CONVERT(0.0);
00321
00322 for(int i = 0; i < count; ++i)
00323 {
00324 result = fv_max(begin[i], result);
00325 }
00326 return result;
00327 }
00328
00329 ScalarValueType GetMaxValue(tf_chanel_t channel, const Interval<ScalarValueType>& range) const
00330 {
00331 ScalarValueType* valueBegin = 0;
00332 ScalarValueType* valueEnd = 0;
00333 int count = 0;
00334 GetValuesForChannel(channel, valueBegin, valueEnd, count);
00335
00336 ScalarValueType* breakpointBegin = 0;
00337 ScalarValueType* breakpointEnd = 0;
00338 GetBreakpointsForChannel(channel, breakpointBegin, breakpointEnd, count);
00339
00340 ScalarValueType result = FLOAT_CONVERT(0.0);
00341
00342 for(int i = 0; i < count; ++i)
00343 {
00344 if( range.Contains(breakpointBegin[i]) )
00345 {
00346 result = fmaxf(valueBegin[i], result);
00347 }
00348 }
00349 result = fv_max(Sample(channel, range.GetLow()), result);
00350 result = fv_max(Sample(channel, range.GetHigh()), result);
00351 return result;
00352 }
00353
00354 ScalarValueType*& DensityBreakpoints() { return m_dbrks_ptr; }
00355 ScalarValueType*& RedBreakpoints() { return m_rbrks_ptr; }
00356 ScalarValueType*& GreenBreakpoints() { return m_gbrks_ptr; }
00357 ScalarValueType*& BlueBreakpoints() { return m_bbrks_ptr; }
00358
00359 ScalarValueType*& DensityValues() { return m_dvals_ptr; }
00360 ScalarValueType*& RedValues() { return m_rvals_ptr; }
00361 ScalarValueType*& GreenValues() { return m_gvals_ptr; }
00362 ScalarValueType*& BlueValues() { return m_bvals_ptr; }
00363
00364 int& NumDensityBreakpoints() { return m_numd_bkrs; }
00365 int& NumRedBreakpoints() { return m_numr_brks; }
00366 int& NumGreenBreakpoints() { return m_numg_brks; }
00367 int& NumBlueBreakpoints() { return m_numb_brks; }
00368
00369 private:
00370 TransferFunction(const TransferFunction&);
00371 TransferFunction& operator=(const TransferFunction&);
00372
00373 ScalarValueType* m_dbrks_ptr;
00374 ScalarValueType* m_rbrks_ptr;
00375 ScalarValueType* m_gbrks_ptr;
00376 ScalarValueType* m_bbrks_ptr;
00377
00378 ScalarValueType* m_dvals_ptr;
00379 ScalarValueType* m_rvals_ptr;
00380 ScalarValueType* m_gvals_ptr;
00381 ScalarValueType* m_bvals_ptr;
00382
00383 int m_numd_bkrs;
00384 int m_numr_brks;
00385 int m_numg_brks;
00386 int m_numb_brks;
00387
00388 };
00389
00390
00391 struct Breakpoint
00392 {
00393 ColorRGB Col;
00394 mfvFloat_t Density;
00395 mfvFloat_t Scalar;
00396 };
00397
00398 class HostTransferFunction
00399 {
00400 public:
00401 HostTransferFunction();
00402 TransferFunction GetOptixObject();
00403
00404 void SetBreakpoint(double s, const ColorRGBA& c);
00405 void SetBreakpoint(double s, const ColorRGBA& c, const mfvFloat_t& density);
00406
00407 bool IsValid() const
00408 {
00409 return m_breakpoints.size() >= 2;
00410 }
00411
00412 const std::map<double, Breakpoint>& GetBreakpoints() const { return m_breakpoints; }
00413
00414 void Clear();
00415
00416
00417
00418 bool& Dirty() { return m_dirty; }
00419
00420 private:
00421 HostTransferFunction(const HostTransferFunction&);
00422 HostTransferFunction& operator=(const HostTransferFunction&);
00423
00424 void UpdateBreakpoints(std::map<double, double>& container);
00425
00426 void SynchronizeDeviceIfNeeded();
00427 void SynchronizeOptiXIfNeeded();
00428 void FreeDeviceMemory();
00429 void AllocateDeviceMemory();
00430 void CopyToDeviceMemory();
00431
00432 std::map<double, Breakpoint> m_breakpoints;
00433
00434 TransferFunction m_localDeviceTransferFunction;
00435 bool m_dirty;
00436 };
00437
00438 }
00439
00440 #endif
00441