2016-04-07 111 views
0

VTK對基本類型(float,int,double等)具有typedefs,並且它爲每個類型分配一個整數。 它們被指定爲here比較vtk數據類型和基本數據類型

函數GetDataType(),例如vtkDataArray返回一個與其中一個類型相對應的整數。 我想比較這個整數與基本數據類型(float,int,double)。

有沒有辦法輕鬆做到這一點?

我對這個的用法是一個模板類,其參數T是一個標量。 我要檢查,如果數據集的標量點數據具有相同的數據類型爲T.

現在,我做什麼,是一種大小對比:

vtkDataArray *scalars = image->GetPointData()->GetScalars(); 
if(scalars->GetDataTypeSize() != sizeof(T)) 
{ 
    std::cerr<<"Incompatible types"<<std::endl; 
} 

但很明顯,floatint都是4號大小,所以它並不真正起作用。

任何想法?

+0

你可以使用type_index,我正在準備一些例子... – norisknofun

回答

0

從幾個地方收集信息後,我總結出沒有辦法簡單地編寫它,而無需在兩個類型列表之間創建映射。

所以,這裏是最優雅的方式,我發現做到這一點:我用的norisknofun的地圖的想法

,但我倒它。 我沒有使用std::type_index(),因爲它似乎可以直接從typeid()的結果中獲取hash_code。 我把這個映射放在一個將基本類型轉換爲VTK類型的函數中,因爲它可以用於其他目的而不僅僅是比較(參見我的other post)。

#include <vtkType.h> 

int GetVTKType(std::size_t hash_code) 
{ 
    static std::map<std::size_t, long> typeMap; 
    if(typeMap.empty()) 
    { 
     typeMap[typeid(void).hash_code()]    = VTK_VOID; 
     typeMap[typeid(char).hash_code()]    = VTK_CHAR; 
     typeMap[typeid(signed char).hash_code()]  = VTK_SIGNED_CHAR; 
     typeMap[typeid(unsigned char).hash_code()]  = VTK_UNSIGNED_CHAR; 
     typeMap[typeid(short).hash_code()]    = VTK_SHORT; 
     typeMap[typeid(unsigned short).hash_code()]  = VTK_UNSIGNED_SHORT; 
     typeMap[typeid(int).hash_code()]    = VTK_INT; 
     typeMap[typeid(unsigned int).hash_code()]  = VTK_UNSIGNED_INT; 
     typeMap[typeid(long).hash_code()]    = VTK_LONG; 
     typeMap[typeid(unsigned long).hash_code()]  = VTK_UNSIGNED_LONG; 
     typeMap[typeid(float).hash_code()]    = VTK_FLOAT; 
     typeMap[typeid(double).hash_code()]    = VTK_DOUBLE; 
     typeMap[typeid(std::string).hash_code()]  = VTK_STRING; 
     typeMap[typeid(long long).hash_code()]   = VTK_LONG_LONG; 
     typeMap[typeid(unsigned long long).hash_code()] = VTK_UNSIGNED_LONG_LONG; 
     typeMap[typeid(int64_t).hash_code()]   = VTK___INT64; 
     typeMap[typeid(uint64_t).hash_code()]   = VTK_UNSIGNED___INT64; 
    } 
    return typeMap[hash_code]; 
} 

因此,要比較VTK數據類型和基本類型(我的模板參數T),我做的:

vtkDataArray *scalars = image->GetPointData()->GetScalars(); 
if(scalars->GetDataType() != GetVTKType(typeid(T).hash_code())) 
{ 
    std::cerr<<"Incompatible types"<<std::endl; 
} 

或者,如果我想要一個漂亮的比較功能norisknofun做它,我可以這樣做:

template < class T > 
bool is_same(long vtkType) 
{ 
    return vtkType != GetVTKType(typeid(T).hash_code()) 
} 

// somewhere.cpp 
if(!is_same<T>(scalars->GetDataType())) 
{ 
    std::cerr<<"Incompatible types"<<std::endl; 
} 
0

我想你必須詳細說明你自己的映射。你的編譯器必須是C++ 11兼容RTTI激活,但現在大多數現代編譯器都支持這個功能。

我不知道什麼是 '位', 'ID_TYPE' 和 '不透明' 類型的C++相當於...

#include <iostream> 
#include <typeinfo> 
#include <typeindex> 
#include <cstdint> 
#include <string> 
#include <map> 

// copy from vtk header, use #include <vtkType.h> instead 
#define VTK_VOID   0 
#define VTK_BIT    1 
#define VTK_CHAR   2 
#define VTK_SIGNED_CHAR 15 
#define VTK_UNSIGNED_CHAR 3 
#define VTK_SHORT   4 
#define VTK_UNSIGNED_SHORT 5 
#define VTK_INT    6 
#define VTK_UNSIGNED_INT 7 
#define VTK_LONG   8 
#define VTK_UNSIGNED_LONG 9 
#define VTK_FLOAT   10 
#define VTK_DOUBLE   11 
#define VTK_ID_TYPE  12 
#define VTK_STRING   13 
#define VTK_OPAQUE   14 
#define VTK_LONG_LONG   16 
#define VTK_UNSIGNED_LONG_LONG 17 
#define VTK___INT64   18 
#define VTK_UNSIGNED___INT64 19 

// vtktypes 
    typedef long vtktypes ; 

    // standard c++ types 
    typedef std::size_t mytypes ; 
    typedef std::map< vtktypes, mytypes> map_t; 

template < class T > 
bool is_same(vtktypes x) 
{ 
    static std::map< vtktypes, mytypes> _map; 
    if(_map.empty()) 
    { 
     _map[VTK_VOID   ] = std::type_index(typeid(void)).hash_code(); 
     //_map[VTK_BIT    ] = std::type_index(typeid(void)).hash_code(); 
     _map[VTK_CHAR   ] = std::type_index(typeid(char)).hash_code(); 
     _map[VTK_SIGNED_CHAR ] = std::type_index(typeid(signed char)).hash_code(); 
     _map[VTK_UNSIGNED_CHAR ] = std::type_index(typeid(unsigned char)).hash_code(); 
     _map[VTK_SHORT   ] = std::type_index(typeid(short)).hash_code(); 
     _map[VTK_UNSIGNED_SHORT ] = std::type_index(typeid(unsigned short)).hash_code(); 
     _map[VTK_INT   ] = std::type_index(typeid(int)).hash_code(); 
     _map[VTK_UNSIGNED_INT ] = std::type_index(typeid(unsigned int)).hash_code(); 
     _map[VTK_LONG   ] = std::type_index(typeid(long)).hash_code(); 
     _map[VTK_UNSIGNED_LONG ] = std::type_index(typeid(unsigned long)).hash_code(); 
     _map[VTK_FLOAT   ] = std::type_index(typeid(float)).hash_code(); 

     _map[VTK_DOUBLE   ] = std::type_index(typeid(double)).hash_code(); 
     //_map[VTK_ID_TYPE   ] = type_index(typeid()).hash_code(); 
     _map[VTK_STRING   ] = std::type_index(typeid(std::string)).hash_code(); 
     //_map[VTK_OPAQUE   ] = type_index(typeid(void)).hash_code(); 
     _map[VTK_LONG_LONG   ]= std::type_index(typeid(long long)).hash_code(); 
     _map[VTK_UNSIGNED_LONG_LONG]= std::type_index(typeid(unsigned long long)).hash_code(); 
     _map[VTK___INT64   ]= std::type_index(typeid(int64_t)).hash_code(); 
     _map[VTK_UNSIGNED___INT64 ]= std::type_index(typeid(uint64_t)).hash_code(); 
    } 

    map_t::iterator it = _map.find(x); 
    return (it != _map.end()) && it->second == std::type_index(typeid(T)).hash_code(); 
} 

int main() 
{ 
    std::cout << "is same ? " << is_same<char>(2) << std::endl ; 
    std::cout << "is same ? " << is_same<std::string>(13) << std::endl ;  

    return 0; 
} 

在你的情況,你可以用它這樣的:

vtkDataArray *scalars = image->GetPointData()->GetScalars(); 
if(!is_same<T>(scalars->GetDataTypeSize())) 
{ 
    std::cerr<<"Incompatible types"<<std::endl; 
}