比较vtk数据类型和基本数据类型
Compare vtk data types and basic data types
VTK 具有基本类型(float、int、double 等)的类型定义,并且它为每种类型分配一个整数。
它们被指定为 here.
函数GetDataType()
,例如vtkDataArray
中的returns一个整数,对应其中一种类型。
我想将该整数与基本数据类型(float、int、double)进行比较。
有没有办法轻松做到这一点?
我对它的用法是一个模板class,其中参数 T 是一个标量。
我想检查数据集的标量点数据是否具有与T相同的数据类型。
目前,我所做的是字体大小比较:
vtkDataArray *scalars = image->GetPointData()->GetScalars();
if(scalars->GetDataTypeSize() != sizeof(T))
{
std::cerr<<"Incompatible types"<<std::endl;
}
但很明显,float
和int
都是4号的,所以它并没有真正起作用。
有什么想法吗?
我猜你必须详细说明你自己的映射。您的编译器必须符合 c++11 并激活 RTTI,但现在大多数现代编译器都支持此功能。
我不知道 'bit'、'id_type' 和 'opaque' 类型的 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;
}
从几个地方收集信息后,我得出结论,如果不自己在两个类型列表之间创建映射,就无法简单地编写它。
所以,这是我发现的最优雅的方法:
我用了norisknofun的地图的思路,但是我倒过来了。
我没有使用 std::type_index()
因为看起来你可以直接从 typeid()
的结果中得到 hash_code。
我将此映射放在一个将基本类型转换为 VTK 类型的函数中,因为它可以用于其他目的,而不仅仅是比较(参见我的 )。
#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;
}
VTK 具有基本类型(float、int、double 等)的类型定义,并且它为每种类型分配一个整数。 它们被指定为 here.
函数GetDataType()
,例如vtkDataArray
中的returns一个整数,对应其中一种类型。
我想将该整数与基本数据类型(float、int、double)进行比较。
有没有办法轻松做到这一点?
我对它的用法是一个模板class,其中参数 T 是一个标量。 我想检查数据集的标量点数据是否具有与T相同的数据类型。
目前,我所做的是字体大小比较:
vtkDataArray *scalars = image->GetPointData()->GetScalars();
if(scalars->GetDataTypeSize() != sizeof(T))
{
std::cerr<<"Incompatible types"<<std::endl;
}
但很明显,float
和int
都是4号的,所以它并没有真正起作用。
有什么想法吗?
我猜你必须详细说明你自己的映射。您的编译器必须符合 c++11 并激活 RTTI,但现在大多数现代编译器都支持此功能。
我不知道 'bit'、'id_type' 和 'opaque' 类型的 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;
}
从几个地方收集信息后,我得出结论,如果不自己在两个类型列表之间创建映射,就无法简单地编写它。
所以,这是我发现的最优雅的方法:
我用了norisknofun的地图的思路,但是我倒过来了。
我没有使用 std::type_index()
因为看起来你可以直接从 typeid()
的结果中得到 hash_code。
我将此映射放在一个将基本类型转换为 VTK 类型的函数中,因为它可以用于其他目的,而不仅仅是比较(参见我的
#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;
}