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
00078 class SoVolumeHistogram
00079 {
00080 public:
00084 SoVolumeHistogram(const SbDataType &dataType);
00085
00089 ~SoVolumeHistogram();
00090
00096 void setInputValueRange( double rangeMin, double rangeMax );
00097
00102 void setUndefinedValue( const double undefinedValue)
00103 { m_undefinedValue=undefinedValue; }
00104
00109 double getUndefinedValue() const
00110 { return m_undefinedValue; };
00111
00116 size_t getHistoSize() const;
00117
00124 int64_t* getHistogram();
00125
00130 int64_t getNumValues(size_t entry);
00131
00135 int64_t getValue(size_t entry);
00136
00140 double getValueD(size_t entry);
00141
00146 int64_t getMinValue() const;
00147
00152 int64_t getMaxValue() const;
00153
00158 double getMinValueD() const;
00159
00164 double getMaxValueD() const;
00165
00170 double getMax() const;
00171
00176 double getMin() const;
00177
00182 int getNumSignificantBits() const;
00183
00188 inline void addValues(SoBufferObject* values, const int numValues);
00189
00193 inline void addValues(SoBufferObject* values, const SbVec3i32& arrayDim);
00194
00198 void addValues(SoBufferObject* values, const SbVec3i32& arrayDim, const SbBox3i32& range);
00199
00203 void set(const std::vector<int64_t> & histo);
00204
00208 void set(const std::vector<int64_t>& histo, const std::vector<double>& values);
00209
00213 template<typename T> inline size_t getEntry(T value) const;
00214
00224 static void computeMinMax(
00225 SoBufferObject* valuesBuffer,
00226 const SbDataType& dataType,
00227 const SbVec3i32& arrayDim,
00228 const SbBox3i32& range,
00229 double& min,
00230 double& max
00231 );
00232
00243 static void computeMinMaxWithUndefined(
00244 SoBufferObject* valuesBuffer,
00245 const double undefinedValue,
00246 const SbDataType& dataType,
00247 const SbVec3i32& arrayDim,
00248 const SbBox3i32& range,
00249 double& min,
00250 double& max
00251 );
00252
00260 static void computeMinMax(
00261 void* valuesBuffer,
00262 const SbDataType& dataType,
00263 const SbVec3i32& arrayDim,
00264 SbVec2d& minMax);
00265
00274 static void computeMinMaxWithUndefined(
00275 void* valuesBuffer,
00276 const double undefinedValue,
00277 const SbDataType& dataType,
00278 const SbVec3i32& arrayDim,
00279 SbVec2d& minMax
00280 );
00281
00282 #if 1 SoDEPRECATED
00289 int* getHistogram32();
00290
00291 #endif
00293 private:
00294
00297 static void initClass();
00298 static void exitClass();
00299
00300 private:
00304 template<typename T> inline size_t getEntryInternal(T value) const;
00305
00311 template<typename T> inline size_t getEntryCaster(T value) const;
00312
00314 unsigned int computeNumSignificantBits() const;
00315
00316 std::vector<int64_t> m_histo;
00317 std::vector<int> m_histo32;
00318 int64_t m_valueMin;
00319 int64_t m_valueMax;
00320 double m_valueMinD;
00321 double m_valueMaxD;
00322 unsigned int m_numSignificantBits;
00323
00324 SbDataType m_dataType;
00325 double m_rangeMin;
00326 double m_rangeMax;
00327 double m_undefinedValue;
00328
00329
00330 template <typename T>
00331 void makeStat(
00332 const void* values,
00333 const SbVec3i32& arrayDim,
00334 const SbBox3i32& range
00335 );
00336
00337 static SoArithmetic* m_arithmeticInterface;
00338 };
00339
00340
00341 void
00342 SoVolumeHistogram::addValues(SoBufferObject* values, const int numValues)
00343 {
00344 addValues(values, SbVec3i32(numValues, 1, 1), SbBox3i32(SbVec3i32(0, 0, 0), SbVec3i32(numValues, 1, 1)));
00345 }
00346
00347
00348 void SoVolumeHistogram::addValues(SoBufferObject* values, const SbVec3i32& arrayDim)
00349 {
00350 addValues(values, arrayDim, SbBox3i32(SbVec3i32(0,0,0),arrayDim));
00351 }
00352
00353
00354 template<typename T> size_t
00355 SoVolumeHistogram::getEntryInternal(T value) const
00356 {
00357 assert(m_dataType.isInteger());
00358 assert(sizeof(T) <= 4);
00359 size_t offset = 0;
00360 size_t factor = 1;
00361
00362 if ( std::numeric_limits<T>::is_signed )
00363 offset = (sizeof(T) >= 2) ? 0x8000 : 0x80;
00364
00365 if ( sizeof(T) == 4 )
00366 factor = (size_t)0x10000;
00367
00368 size_t entry = (size_t)(value/int64_t(factor)+int64_t(offset));
00369
00370 return entry;
00371 }
00372
00373
00374 template<typename T> size_t
00375 SoVolumeHistogram::getEntryCaster(T value) const
00376 {
00377 return getEntryInternal(T(value));
00378 }
00379
00380
00381 template<typename T> size_t
00382 SoVolumeHistogram::getEntry(T value) const
00383 {
00384 size_t ret = 0;
00385
00386 switch (m_dataType)
00387 {
00388 case SbDataType::UNSIGNED_SHORT:
00389 ret = getEntryInternal<unsigned short>((unsigned short)value);
00390 break;
00391 case SbDataType::UNSIGNED_INT32:
00392 ret = getEntryInternal<uint32_t>((uint32_t)value);
00393 break;
00394 case SbDataType::SIGNED_BYTE:
00395 ret = getEntryInternal<signed char>((signed char)value);
00396 break;
00397 case SbDataType::SIGNED_SHORT:
00398 ret = getEntryInternal<signed short>((signed short)value);
00399 break;
00400 case SbDataType::SIGNED_INT32:
00401 ret = getEntryInternal<int32_t>((int32_t)value);
00402 break;
00403 case SbDataType::FLOAT:
00404 ret = getEntryInternal<float>((float)value);
00405 break;
00406 case SbDataType::UNSIGNED_BYTE:
00407 ret = getEntryInternal<unsigned char>((unsigned char)value);
00408 break;
00409 case SbDataType::DOUBLE:
00410 ret = getEntryInternal<double>((double)value);
00411 break;
00412 default:
00413 assert(0);
00414 break;
00415 }
00416
00417 return ret;
00418 }
00419
00420
00421 template<> inline size_t
00422 SoVolumeHistogram::getEntryInternal<float>(float value) const
00423 {
00424 assert(m_dataType == SbDataType::FLOAT);
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
00435 template<> inline size_t
00436 SoVolumeHistogram::getEntryInternal<double>(double value) const
00437 {
00438 assert(m_dataType == SbDataType::DOUBLE);
00439 if ( m_rangeMax == m_rangeMin )
00440 return 0;
00441 double factorDouble = 0.0f;
00442 factorDouble = 0xffff / (m_rangeMax - m_rangeMin);
00443 size_t entry = (size_t)((value-m_rangeMin)*factorDouble);
00444
00445 return SbMathHelper::Clamp(entry, (size_t)0, (size_t)0xffff);
00446 }
00447
00448 #ifdef _MSC_VER
00449 #pragma warning( pop )
00450 #endif
00451
00452 #endif
00453
00454
00455