Detects data modality from dimension information.
Consolidates modality detection logic that was duplicated across analyzers. Uses dimension roles and count to determine appropriate processing approach.
73{
74 if (dimensions.empty()) {
75 return DataModality::UNKNOWN;
76 }
77
78 size_t time_dims = 0, spatial_dims = 0, channel_dims = 0, frequency_dims = 0, custom_dims = 0;
79 size_t total_spatial_elements = 1;
80 size_t total_channels = 0;
81
82 for (const auto& dim : dimensions) {
83 if (dim.grouping) {
84 switch (dim.role) {
85 case DataDimension::Role::POSITION:
86 return DataModality::VERTEX_POSITIONS_3D;
87 case DataDimension::Role::NORMAL:
88 return DataModality::VERTEX_NORMALS_3D;
89 case DataDimension::Role::TANGENT:
90 case DataDimension::Role::BITANGENT:
91 return DataModality::VERTEX_TANGENTS_3D;
92 case DataDimension::Role::UV:
93 return DataModality::TEXTURE_COORDS_2D;
94 case DataDimension::Role::COLOR:
95 if (dim.grouping->count == 3)
96 return DataModality::VERTEX_COLORS_RGB;
97 if (dim.grouping->count == 4)
98 return DataModality::VERTEX_COLORS_RGBA;
99 break;
100 default:
101 if (dim.grouping->count == 16)
102 return DataModality::TRANSFORMATION_MATRIX;
103 break;
104 }
105 }
106 }
107
108 for (const auto& dim : dimensions) {
109 switch (dim.role) {
110 case DataDimension::Role::TIME:
111 time_dims++;
112 break;
113 case DataDimension::Role::SPATIAL_X:
114 case DataDimension::Role::SPATIAL_Y:
115 case DataDimension::Role::SPATIAL_Z:
116 spatial_dims++;
117 total_spatial_elements *= dim.size;
118 break;
119 case DataDimension::Role::CHANNEL:
120 channel_dims++;
121 total_channels += dim.size;
122 break;
123 case DataDimension::Role::FREQUENCY:
124 frequency_dims++;
125 break;
126 case DataDimension::Role::CUSTOM:
127 default:
128 custom_dims++;
129 break;
130 }
131 }
132
133 if (time_dims == 1 && spatial_dims == 0 && frequency_dims == 0) {
134 if (channel_dims == 0) {
135 return DataModality::AUDIO_1D;
136 } else if (channel_dims == 1) {
137 return (total_channels <= 1) ? DataModality::AUDIO_1D : DataModality::AUDIO_MULTICHANNEL;
138 } else {
139 return DataModality::AUDIO_MULTICHANNEL;
140 }
141 }
142
143 if (time_dims >= 1 && frequency_dims >= 1) {
144 if (spatial_dims == 0 && channel_dims <= 1) {
145 return DataModality::SPECTRAL_2D;
146 }
147 return DataModality::TENSOR_ND;
148 }
149
150 if (spatial_dims >= 2 && time_dims == 0) {
151 if (spatial_dims == 2) {
152 if (channel_dims == 0) {
153 return DataModality::IMAGE_2D;
154 } else if (channel_dims == 1 && total_channels >= 3) {
155 return DataModality::IMAGE_COLOR;
156 } else {
157 return DataModality::IMAGE_2D;
158 }
159 } else if (spatial_dims == 3) {
160 return DataModality::VOLUMETRIC_3D;
161 }
162 }
163
164 if (time_dims >= 1 && spatial_dims >= 2) {
165 if (spatial_dims == 2) {
166 if (channel_dims == 0 || (channel_dims == 1 && total_channels <= 1)) {
167 return DataModality::VIDEO_GRAYSCALE;
168 } else {
169 return DataModality::VIDEO_COLOR;
170 }
171 }
172 return DataModality::TENSOR_ND;
173 }
174
175 if (spatial_dims == 2 && time_dims == 0 && channel_dims >= 1) {
176 if (total_spatial_elements >= 64 && total_channels >= 1) {
177 return DataModality::TEXTURE_2D;
178 }
179 }
180
181 return DataModality::TENSOR_ND;
182}