Non-virtual version of vtkDataArrayTemplate

随声附和 提交于 2019-12-12 02:53:10

问题


I have a template class myClass<T>, where T can be a scalar (float, int, double, etc.) I would like to create a vtkFloatArray, vtkIntArray, or vtkDoubleArray, depending on the type T.

I thought that vtkDataArrayTemplate<T> would be a good solution. Unfortunately, it is a virtual class, so I can't write this :

vtkSmartPointer< vtkDataArrayTemplate<T> > array =  vtkSmartPointer<vtkDataArrayTemplate<T> >::New();

because when I try to instantiate a myClass, I get the error :

error: invalid conversion from ‘vtkObject*’ to ‘vtkDataArrayTemplate<float>*’ [-fpermissive]`

I think it's because vtkDataArrayTemplate::New() doesn't exist (because the class is virtual), so vtkObject::New() is called instead. Then we understand that it can't transform a vtkObject into a vtkDataArrayTemplate.

So my question is:

Is there an non-virtual version of vtkDataArrayTemplate that would allow me to create a vtkFloatArray when T is float, vtkDoubleArray when T is double, etc. ?

P.S: I use VTK 6.0.0


回答1:


Following the same logic of the other vtk question, you can make a factory with the a map of type

std::map< vtktypes , std::function< void*() > > _map;

std::function< void*() > aims to be a simple object creator, returning void* which then needs to be statically casted into the target type.

like :

_map[VTK_INT] = [](){ return new vtkFloatArray(); }



回答2:


An email to the vtk-users mailing list helped me on this too. A useful static function in vtkDataArray has been pointed to me:

vtkDataArray::CreateDataArray(int dataType)

It allows to create a data array of the type dataType.

Now, to transform the template parameter T into a vtk type, I used the code I mentionned in this other post: (thank you norisknofun)

#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];
}

So the final code is:

vtkDataArray *array = 
    vtkDataArray::CreateDataArray(GetVTKType(typeid(T).hash_code()));


来源:https://stackoverflow.com/questions/36475138/non-virtual-version-of-vtkdataarraytemplate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!