00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef _SO_VOLUME_HISTOGRAM_
00025 #define _SO_VOLUME_HISTOGRAM_
00026
00027 #ifdef _MSC_VER
00028 #pragma warning( push )
00029 #pragma warning(disable:4251)
00030 #pragma warning(disable:4127)
00031 #endif
00032
00033 #include <Inventor/SbDataType.h>
00034 #include <Inventor/SbLinear.h>
00035 #include <Inventor/helpers/SbDataTypeMacros.h>
00036
00037 #include <Inventor/STL/limits>
00038 #include <Inventor/STL/vector>
00039
00040 class SoBufferObject;
00041 class SoArithmetic;
00042
00076 class SoVolumeHistogram
00077 {
00078 public:
00082 SoVolumeHistogram(const SbDataType &dataType);
00083
00087 ~SoVolumeHistogram();
00088
00094 void setInputValueRange( double rangeMin, double rangeMax );
00095
00100 void setUndefinedValue( const double undefinedValue)
00101 { m_undefinedValue=undefinedValue; }
00102
00107 double getUndefinedValue() const
00108 { return m_undefinedValue; };
00109
00114 size_t getHistoSize() const;
00115
00122 int64_t* getHistogram();
00123
00128 int64_t getNumValues(size_t entry);
00129
00133 int64_t getValue(size_t entry);
00134
00138 double getValueD(size_t entry);
00139
00144 int64_t getMinValue() const;
00145
00150 int64_t getMaxValue() const;
00151
00156 double getMinValueD() const;
00157
00162 double getMaxValueD() const;
00163
00168 double getMax() const;
00169
00174 double getMin() const;
00175
00180 int getNumSignificantBits() const;
00181
00186 inline void addValues(SoBufferObject* values, const int numValues);
00187
00191 inline void addValues(SoBufferObject* values, const SbVec3i32& arrayDim);
00192
00196 void addValues(SoBufferObject* values, const SbVec3i32& arrayDim, const SbBox3i32& range);
00197
00201 void set(const std::vector<int64_t> & histo);
00202
00206 void set(const std::vector<int64_t>& histo, const std::vector<double>& values);
00207
00211 template<typename T> inline size_t getEntry(T value) const;
00212
00222 static void computeMinMax(
00223 SoBufferObject* valuesBuffer,
00224 const SbDataType& dataType,
00225 const SbVec3i32& arrayDim,
00226 const SbBox3i32& range,
00227 double& min,
00228 double& max
00229 );
00230
00241 static void computeMinMaxWithUndefined(
00242 SoBufferObject* valuesBuffer,
00243 const double undefinedValue,
00244 const SbDataType& dataType,
00245 const SbVec3i32& arrayDim,
00246 const SbBox3i32& range,
00247 double& min,
00248 double& max
00249 );
00250
00258 static void computeMinMax(
00259 void* valuesBuffer,
00260 const SbDataType& dataType,
00261 const SbVec3i32& arrayDim,
00262 SbVec2d& minMax);
00263
00272 static void computeMinMaxWithUndefined(
00273 void* valuesBuffer,
00274 const double undefinedValue,
00275 const SbDataType& dataType,
00276 const SbVec3i32& arrayDim,
00277 SbVec2d& minMax
00278 );
00279
00280 private:
00284 static void initClass();
00285 static void exitClass();
00286
00287 private:
00291 template<typename T> inline size_t getEntryInternal(T value) const;
00292
00298 template<typename T> inline size_t getEntryCaster(T value) const;
00299
00301 unsigned int computeNumSignificantBits() const;
00302
00303 std::vector<int64_t> m_histo;
00304 int64_t m_valueMin;
00305 int64_t m_valueMax;
00306 double m_valueMinD;
00307 double m_valueMaxD;
00308 unsigned int m_numSignificantBits;
00309
00310 SbDataType m_dataType;
00311 double m_rangeMin;
00312 double m_rangeMax;
00313 double m_undefinedValue;
00314
00315
00316 template <typename T>
00317 void makeStat(
00318 const void* values,
00319 const SbVec3i32& arrayDim,
00320 const SbBox3i32& range
00321 );
00322
00323 static SoArithmetic* s_arithmeticInterface;
00324 };
00325
00326
00327 void
00328 SoVolumeHistogram::addValues(SoBufferObject* values, const int numValues)
00329 {
00330 addValues(values, SbVec3i32(numValues, 1, 1), SbBox3i32(SbVec3i32(0, 0, 0), SbVec3i32(numValues, 1, 1)));
00331 }
00332
00333
00334 void SoVolumeHistogram::addValues(SoBufferObject* values, const SbVec3i32& arrayDim)
00335 {
00336 addValues(values, arrayDim, SbBox3i32(SbVec3i32(0,0,0),arrayDim));
00337 }
00338
00339
00340 template<typename T> size_t
00341 SoVolumeHistogram::getEntryInternal(T value) const
00342 {
00343 assert(m_dataType.isInteger());
00344 assert(sizeof(T) <= 4);
00345 size_t offset = 0;
00346 size_t factor = 1;
00347
00348 if ( std::numeric_limits<T>::is_signed )
00349 offset = (sizeof(T) >= 2) ? 0x8000 : 0x80;
00350
00351 if ( sizeof(T) == 4 )
00352 factor = (size_t)0x10000;
00353
00354 size_t entry = (size_t)(value/int64_t(factor)+int64_t(offset));
00355
00356 return entry;
00357 }
00358
00359
00360 template<typename T> size_t
00361 SoVolumeHistogram::getEntryCaster(T value) const
00362 {
00363 return getEntryInternal(T(value));
00364 }
00365
00366
00367 template<typename T> size_t
00368 SoVolumeHistogram::getEntry(T value) const
00369 {
00370 size_t ret = 0;
00371
00372 switch (m_dataType)
00373 {
00374 case SbDataType::UNSIGNED_SHORT:
00375 ret = getEntryInternal<unsigned short>((unsigned short)value);
00376 break;
00377 case SbDataType::UNSIGNED_INT32:
00378 ret = getEntryInternal<uint32_t>((uint32_t)value);
00379 break;
00380 case SbDataType::SIGNED_BYTE:
00381 ret = getEntryInternal<signed char>((signed char)value);
00382 break;
00383 case SbDataType::SIGNED_SHORT:
00384 ret = getEntryInternal<signed short>((signed short)value);
00385 break;
00386 case SbDataType::SIGNED_INT32:
00387 ret = getEntryInternal<int32_t>((int32_t)value);
00388 break;
00389 case SbDataType::FLOAT:
00390 ret = getEntryInternal<float>((float)value);
00391 break;
00392 case SbDataType::UNSIGNED_BYTE:
00393 ret = getEntryInternal<unsigned char>((unsigned char)value);
00394 break;
00395 case SbDataType::DOUBLE:
00396 ret = getEntryInternal<double>((double)value);
00397 break;
00398 default:
00399 assert(0);
00400 break;
00401 }
00402
00403 return ret;
00404 }
00405
00406
00407 template<> inline size_t
00408 SoVolumeHistogram::getEntryInternal<float>(float value) const
00409 {
00410 assert(m_dataType == SbDataType::FLOAT);
00411 if ( m_rangeMax == m_rangeMin )
00412 return 0;
00413 double factorDouble = 0.0f;
00414 factorDouble = 0xffff / (m_rangeMax - m_rangeMin);
00415 size_t entry = (size_t)((value-m_rangeMin)*factorDouble);
00416
00417 return SbMathHelper::Clamp(entry, (size_t)0, (size_t)0xffff);
00418 }
00419
00420
00421 template<> inline size_t
00422 SoVolumeHistogram::getEntryInternal<double>(double value) const
00423 {
00424 assert(m_dataType == SbDataType::DOUBLE);
00425 if ( m_rangeMax == m_rangeMin )
00426 return 0;
00427 double factorDouble = 0.0f;
00428 factorDouble = 0xffff / (m_rangeMax - m_rangeMin);
00429 size_t entry = (size_t)((value-m_rangeMin)*factorDouble);
00430
00431 return SbMathHelper::Clamp(entry, (size_t)0, (size_t)0xffff);
00432 }
00433
00434 #ifdef _MSC_VER
00435 #pragma warning( pop )
00436 #endif
00437
00438 #endif
00439
00440
00441