forked from InsightSoftwareConsortium/itk-wasm
/
itkSupportInputMeshTypes.h
175 lines (152 loc) · 5.54 KB
/
itkSupportInputMeshTypes.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/*=========================================================================
*
* Copyright NumFOCUS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*=========================================================================*/
#ifndef itkSupportInputMeshTypes_h
#define itkSupportInputMeshTypes_h
#include "itkPipeline.h"
#include "itkWASMPixelTypeFromIOPixelEnum.h"
#include "itkWASMComponentTypeFromIOComponentEnum.h"
#include "itkMeshConvertPixelTraits.h"
#include "itkWASMMapComponentType.h"
#include "itkWASMMapPixelType.h"
#include "itkMesh.h"
#include "itkMeshIOBase.h"
#include "itkMeshIOFactory.h"
namespace itk
{
namespace wasm
{
struct InterfaceMeshType
{
unsigned int dimension{2};
std::string componentType{"uint8"};
std::string pixelType{"Scalar"};
unsigned int components{1};
};
bool lexical_cast(const std::string &input, InterfaceMeshType & meshType);
/** \class SupportInputMeshTypes
*
* \brief Instantiatiate a Pipeline functor over multiple pixel types and dimensions and match to the input mesh type.
*
* Instantiate the PipelineFunctor (function object) over multiple pixel types and mesh dimensions.
* If the input mesh matches these pixel types or dimensions, use the compile-time optimized pipeline for that mesh type.
* Otherwise, exit the pipeline with an error identifying the unsupported mesh type.
*
* Example usage:
*
```
template<typename TMesh>
class PipelineFunctor
{
public:
int operator()(itk::wasm::Pipeline & pipeline)
{
using MeshType = TMesh;
using InputMeshType = itk::wasm::InputMesh<MeshType>;
InputMeshType inputMesh;
pipeline.add_option("InputMesh", inputMesh, "The input mesh")->required();
```
[...]
```
int
main(int argc, char * argv[])
{
itk::wasm::Pipeline pipeline("Test supporting multiple input mesh types", argc, argv);
// Supports the pixels types uint8_t, float
// Supports the mesh dimensions 2, 3
return itk::wasm::SupportInputMeshTypes<PipelineFunctor,
uint8_t,
float>
::Dimensions<2U,3U>("InputMesh", pipeline);
}
```
* It is assumed that the cell and point data will have the same pixel type.
*
* The number of pixel components is taken from the point pixel data. If there are 0 point pixel data components,
* the cell pixel data components are queried.
*
* \ingroup WebAssemblyInterface
*/
template<template <typename TMesh> class TPipelineFunctor, typename ...TPixels>
class
SupportInputMeshTypes
{
public:
template<unsigned int ...VDimensions>
static int
Dimensions(const std::string & inputMeshOptionName, Pipeline & pipeline)
{
InterfaceMeshType meshType;
auto tempOption = pipeline.add_option(inputMeshOptionName, meshType, "Read mesh type.");
ITK_WASM_PRE_PARSE(pipeline);
pipeline.remove_option(tempOption);
return IterateDimensions<VDimensions...>(pipeline, meshType);
}
private:
template<unsigned int VDimension, typename TPixel, typename ...TPixelsRest>
static int
IteratePixelTypes(Pipeline & pipeline, const InterfaceMeshType & meshType)
{
constexpr unsigned int Dimension = VDimension;
using PixelType = TPixel;
using ConvertPixelTraits = MeshConvertPixelTraits<PixelType>;
if ( meshType.components == 0
|| meshType.componentType == MapComponentType<typename ConvertPixelTraits::ComponentType>::ComponentString
&& meshType.pixelType == MapPixelType<PixelType>::PixelString)
{
if (meshType.pixelType == "VariableLengthVector" || meshType.pixelType == "VariableSizeMatrix" )
{
// todo: VectorMesh support for ImportMeshFilter?
// using MeshType = itk::VectorMesh<typename ConvertPixelTraits::ComponentType, Dimension>;
// using PipelineType = TPipelineFunctor<MeshType>;
// return PipelineType()(pipeline);
}
else if( meshType.components == ConvertPixelTraits::GetNumberOfComponents() || meshType.components == 0 )
{
using MeshType = Mesh<PixelType, Dimension>;
using PipelineType = TPipelineFunctor<MeshType>;
return PipelineType()(pipeline);
}
}
if constexpr (sizeof...(TPixelsRest) > 0) {
return IteratePixelTypes<VDimension, TPixelsRest...>(pipeline, meshType);
}
std::ostringstream ostrm;
ostrm << "Unsupported pixel type: " << meshType.pixelType << " with component type: " << meshType.componentType << " and components: " << meshType.components;
CLI::Error err("Runtime error", ostrm.str(), 1);
return pipeline.exit(err);
}
template<unsigned int VDimension, unsigned int ...VDimensions>
static int
IterateDimensions(Pipeline & pipeline, const InterfaceMeshType & meshType)
{
if (VDimension == meshType.dimension)
{
return IteratePixelTypes<VDimension, TPixels...>(pipeline, meshType);
}
if constexpr (sizeof...(VDimensions) > 0) {
return IterateDimensions<VDimensions...>(pipeline, meshType);
}
std::ostringstream ostrm;
ostrm << "Unsupported mesh dimension: " << meshType.dimension;
CLI::Error err("Runtime error", ostrm.str(), 1);
return pipeline.exit(err);
}
};
} // end namespace wasm
} // end namespace itk
#endif