11#include " Mesh.hpp"
22#include < Python.h>
3+ #include < string>
34#include < swap.hpp>
45
56#define MAX (x, y ) (((x) > (y)) ? (x) : (y))
@@ -20,6 +21,64 @@ enum VertexFormat
2021 kVertexFormatSInt32
2122};
2223
24+ template <uint8_t componentByteSize>
25+ void unpack_vertexdata_template (uint8_t *componentBytes, uint8_t *vertexData, uint32_t m_VertexCount, uint32_t m_StreamOffset, uint32_t m_StreamStride, uint32_t m_ChannelOffset, uint32_t m_ChannelDimension)
26+ {
27+ const auto channelSize = componentByteSize * m_ChannelDimension;
28+
29+ uint8_t *componentCur = componentBytes;
30+ uint8_t *vertexCur = vertexData;
31+
32+ // move vertexCur to the first vertex
33+ vertexCur += m_StreamOffset + m_ChannelOffset;
34+
35+ for (uint32_t v = 0 ; v < m_VertexCount; v++)
36+ {
37+ memcpy (componentCur, vertexCur, channelSize);
38+ componentCur += channelSize;
39+ vertexCur += m_StreamStride;
40+ }
41+ }
42+
43+ template <uint8_t componentByteSize>
44+ void swap_vertexdata (uint8_t *componentBytes, uint32_t m_VertexCount, uint32_t m_ChannelDimension)
45+ {
46+ if constexpr (componentByteSize == 1 )
47+ {
48+ // do nothing
49+ }
50+ else if constexpr (componentByteSize == 2 )
51+ {
52+ uint16_t *componentUints = (uint16_t *)componentBytes;
53+ for (uint32_t i = 0 ; i < m_VertexCount * m_ChannelDimension; i++)
54+ {
55+ swap_any_inplace (componentUints++);
56+ }
57+ }
58+ else if constexpr (componentByteSize == 4 )
59+ {
60+ uint32_t *componentUints = (uint32_t *)componentBytes;
61+ for (uint32_t i = 0 ; i < m_VertexCount * m_ChannelDimension; i++)
62+ {
63+ swap_any_inplace (componentUints++);
64+ }
65+ }
66+ else if constexpr (componentByteSize == 8 )
67+ {
68+ uint64_t *componentUints = (uint64_t *)componentBytes;
69+ for (uint32_t i = 0 ; i < m_VertexCount * m_ChannelDimension; i++)
70+ {
71+ swap_any_inplace (componentUints++);
72+ }
73+ }
74+ else
75+ {
76+ const auto compoentByteSizeStr = std::to_string (componentByteSize);
77+ const auto error_message = " Swap not implemented for this size: " + compoentByteSizeStr;
78+ PyErr_SetString (PyExc_ValueError, error_message.c_str ());
79+ }
80+ }
81+
2382PyObject *unpack_vertexdata (PyObject *self, PyObject *args)
2483{
2584 // define vars
@@ -63,148 +122,38 @@ PyObject *unpack_vertexdata(PyObject *self, PyObject *args)
63122 }
64123 uint8_t *componentBytes = (uint8_t *)PyBytes_AS_STRING (res);
65124
66- for ( uint32_t v = 0 ; v < m_VertexCount; v++ )
125+ switch (componentByteSize )
67126 {
68- uint32_t vertexOffset = m_StreamOffset + m_ChannelOffset + m_StreamStride * v;
69- for (uint32_t d = 0 ; d < m_ChannelDimension; d++)
127+ case 1 :
128+ unpack_vertexdata_template<1 >(componentBytes, vertexData, m_VertexCount, m_StreamOffset, m_StreamStride, m_ChannelOffset, m_ChannelDimension);
129+ break ;
130+ case 2 :
131+ unpack_vertexdata_template<2 >(componentBytes, vertexData, m_VertexCount, m_StreamOffset, m_StreamStride, m_ChannelOffset, m_ChannelDimension);
132+ if (swap)
70133 {
71- uint32_t vertexDataOffset = vertexOffset + componentByteSize * d;
72- uint32_t componentOffset = componentByteSize * (v * m_ChannelDimension + d);
73- memcpy (componentBytes + componentOffset, vertexData + vertexDataOffset, componentByteSize);
134+ swap_vertexdata<2 >(componentBytes, m_VertexCount, m_ChannelDimension);
74135 }
75- }
76-
77- if (swap) // swap bytes
78- {
79- if (componentByteSize == 2 )
136+ break ;
137+ case 4 :
138+ unpack_vertexdata_template<4 >(componentBytes, vertexData, m_VertexCount, m_StreamOffset, m_StreamStride, m_ChannelOffset, m_ChannelDimension);
139+ if (swap)
80140 {
81- uint16_t *componentUints = (uint16_t *)componentBytes;
82- for (uint32_t i = 0 ; i < componentBytesLength; i += 2 )
83- {
84- swap_any_inplace (componentUints++);
85- }
141+ swap_vertexdata<4 >(componentBytes, m_VertexCount, m_ChannelDimension);
86142 }
87- else if (componentByteSize == 4 )
143+ break ;
144+ case 8 :
145+ unpack_vertexdata_template<8 >(componentBytes, vertexData, m_VertexCount, m_StreamOffset, m_StreamStride, m_ChannelOffset, m_ChannelDimension);
146+ if (swap)
88147 {
89-
90- uint32_t *componentUints = (uint32_t *)componentBytes;
91- for (uint32_t i = 0 ; i < componentBytesLength; i += 4 )
92- {
93- swap_any_inplace (componentUints++);
94- }
148+ swap_vertexdata<8 >(componentBytes, m_VertexCount, m_ChannelDimension);
95149 }
150+ break ;
151+ default :
152+ PyBuffer_Release (&vertexDataView);
153+ PyErr_SetString (PyExc_ValueError, " Unsupported component byte size" );
154+ return nullptr ;
96155 }
97156
98157 PyBuffer_Release (&vertexDataView);
99158 return res;
100-
101- // fast enough in Python
102- // uint32_t itemCount = componentBytesLength / componentByteSize;
103- // PyObject *lst = PyList_New(itemCount);
104- // if (!lst)
105- // return nullptr;
106-
107- // switch (format)
108- // {
109- // case kVertexFormatFloat:
110- // {
111- // float *items = (float *)componentBytes;
112- // for (uint32_t i = 0; i < itemCount; i++)
113- // {
114- // PyList_SetItem(lst, i, PyFloat_FromDouble((double)*items++));
115- // }
116- // // result[i] = BitConverter.ToSingle(inputBytes, i * 4);
117- // break;
118- // }
119- // case kVertexFormatFloat16:
120- // {
121- // uint16_t *items = (uint16_t *)componentBytes;
122- // for (uint32_t i = 0; i < itemCount; i++)
123- // {
124- // double x = _PyFloat_Unpack2(items++, 0);
125- // if (x == -1.0 && PyErr_Occurred())
126- // {
127- // return nullptr;
128- // }
129- // PyList_SetItem(lst, i, PyFloat_FromDouble(x));
130- // }
131- // // result[i] = Half.ToHalf(inputBytes, i * 2);
132- // break;
133- // }
134- // case kVertexFormatUNorm8:
135- // {
136- // uint8_t *items = componentBytes;
137- // for (uint32_t i = 0; i < itemCount; i++)
138- // {
139- // PyList_SetItem(lst, i, PyFloat_FromDouble((double)(*items++ / 255.0f)));
140- // }
141- // // result[i] = inputBytes[i] / 255f;
142- // break;
143- // }
144- // case kVertexFormatSNorm8:
145- // {
146- // int8_t *items = (int8_t *)componentBytes;
147- // for (uint32_t i = 0; i < itemCount; i++)
148- // {
149- // PyList_SetItem(lst, i, PyFloat_FromDouble((double)MAX((*items++ / 127.0f), -1.0f)));
150- // }
151- // // result[i] = Math.Max((sbyte)inputBytes[i] / 127f, -1f);
152- // break;
153- // }
154- // case kVertexFormatUNorm16:
155- // {
156- // uint16_t *items = (uint16_t *)componentBytes;
157- // for (uint32_t i = 0; i < itemCount; i++)
158- // {
159- // PyList_SetItem(lst, i, PyFloat_FromDouble((double)(*items++ / 65535.0f)));
160- // }
161- // // result[i] = BitConverter.ToUInt16(inputBytes, i * 2) / 65535f;
162- // break;
163- // }
164- // case kVertexFormatSNorm16:
165- // {
166- // int16_t *items = (int16_t *)componentBytes;
167- // for (uint32_t i = 0; i < itemCount; i++)
168- // {
169- // PyList_SetItem(lst, i, PyFloat_FromDouble((double)MAX((*items++ / 32767.0f), -1.0f)));
170- // }
171- // // result[i] = Math.Max(BitConverter.ToInt16(inputBytes, i * 2) / 32767f, -1f);
172- // break;
173- // }
174- // case kVertexFormatUInt8:
175- // case kVertexFormatSInt8:
176- // {
177- // uint8_t *items = componentBytes;
178- // for (uint32_t i = 0; i < itemCount; i++)
179- // {
180- // PyList_SetItem(lst, i, PyLong_FromUnsignedLong((uint32_t)*items++));
181- // }
182- // // result[i] = inputBytes[i];
183- // break;
184- // }
185- // case kVertexFormatUInt16:
186- // case kVertexFormatSInt16:
187- // {
188- // uint16_t *items = (uint16_t *)componentBytes;
189- // for (uint32_t i = 0; i < itemCount; i++)
190- // {
191- // PyList_SetItem(lst, i, PyLong_FromUnsignedLong((uint32_t)*items++));
192- // }
193- // // result[i] = BitConverter.ToInt16(inputBytes, i * 2);
194- // break;
195- // }
196- // case kVertexFormatUInt32:
197- // case kVertexFormatSInt32:
198- // {
199- // uint32_t *items = (uint32_t *)componentBytes;
200- // for (uint32_t i = 0; i < itemCount; i++)
201- // {
202- // PyList_SetItem(lst, i, PyLong_FromUnsignedLong(*items++));
203- // }
204- // // result[i] = BitConverter.ToInt32(inputBytes, i * 4);
205- // break;
206- // }
207- // }
208- // free(componentBytes);
209- // return lst;
210159}
0 commit comments