-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathutils_bindings.cpp
More file actions
131 lines (118 loc) · 9.51 KB
/
Copy pathutils_bindings.cpp
File metadata and controls
131 lines (118 loc) · 9.51 KB
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
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2026 Fernando Sahmkow
//
// AUTOGENERATED by tools/codegen — do not edit by hand.
// Regenerate via: python -m tools.codegen.codegen utils --backend pybind11
//
// Source headers and `@bind` annotations live under include/whiteout/.
//
// Include order matters here:
// 1. pybind11/pybind11.h sets up the base library
// 2. project headers define whiteout::u32 et al used inside MAKE_OPAQUE
// 3. PYBIND11_MAKE_OPAQUE opts out of stl.h's auto-conversion for our vectors
// 4. pybind11/stl.h, stl_bind.h honor the opaque declarations
#include <pybind11/pybind11.h>
#include <array>
#include <cstdint>
#include <optional>
#include <sstream>
#include <string>
#include <vector>
#include <whiteout/utils/vertex_buffer.h>
#include <whiteout/interfaces.h>
PYBIND11_MAKE_OPAQUE(std::vector<whiteout::u8>);
PYBIND11_MAKE_OPAQUE(std::vector<whiteout::Vector2f>);
PYBIND11_MAKE_OPAQUE(std::vector<whiteout::Vector3f>);
PYBIND11_MAKE_OPAQUE(std::vector<whiteout::Vector4f>);
PYBIND11_MAKE_OPAQUE(std::vector<whiteout::utils::VertexBuffer::Attribute>);
PYBIND11_MAKE_OPAQUE(std::vector<std::string>);
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>
#include <pybind11/operators.h>
#include <pybind11/numpy.h>
namespace py = pybind11;
void bind_utils(py::module_& m) {
py::enum_<whiteout::utils::AttributeClass>(m, "AttributeClass")
.value("POSITION", whiteout::utils::AttributeClass::Position)
.value("NORMAL", whiteout::utils::AttributeClass::Normal)
.value("TANGENT", whiteout::utils::AttributeClass::Tangent)
.value("UV", whiteout::utils::AttributeClass::UV)
.value("COLOR", whiteout::utils::AttributeClass::Color)
.value("BLEND_INDICES", whiteout::utils::AttributeClass::BlendIndices)
.value("BLEND_WEIGHTS", whiteout::utils::AttributeClass::BlendWeights)
.value("BINORMAL", whiteout::utils::AttributeClass::Binormal)
.value("COUNT", whiteout::utils::AttributeClass::Count)
;
py::enum_<whiteout::utils::AttributeEncoding>(m, "AttributeEncoding")
.value("FLOAT32", whiteout::utils::AttributeEncoding::Float32)
.value("FLOAT16", whiteout::utils::AttributeEncoding::Float16)
.value("S_NORM8", whiteout::utils::AttributeEncoding::SNorm8)
.value("S_NORM16", whiteout::utils::AttributeEncoding::SNorm16)
.value("U_NORM8", whiteout::utils::AttributeEncoding::UNorm8)
.value("U_NORM16", whiteout::utils::AttributeEncoding::UNorm16)
.value("U_INT8", whiteout::utils::AttributeEncoding::UInt8)
.value("U_INT16", whiteout::utils::AttributeEncoding::UInt16)
.value("U_INT32", whiteout::utils::AttributeEncoding::UInt32)
.value("INT8", whiteout::utils::AttributeEncoding::Int8)
.value("INT16", whiteout::utils::AttributeEncoding::Int16)
.value("INT32", whiteout::utils::AttributeEncoding::Int32)
;
py::class_<whiteout::utils::VertexBuffer::Attribute>(m, "VertexBufferAttribute")
.def(py::init<>())
.def(py::init([](whiteout::utils::AttributeClass attr_class, whiteout::utils::AttributeEncoding encoding, whiteout::u64 component_count, whiteout::u64 offset) {
return whiteout::utils::VertexBuffer::Attribute{attr_class, encoding, component_count, offset};
}), py::arg("attr_class"), py::arg("encoding"), py::arg("component_count"), py::arg("offset"))
.def("__repr__", [](const whiteout::utils::VertexBuffer::Attribute& self) {
std::ostringstream oss;
oss << "VertexBufferAttribute(";
oss << "attr_class=" << static_cast<int>(self.attr_class) << ", ";
oss << "encoding=" << static_cast<int>(self.encoding) << ", ";
oss << "component_count=" << self.component_count << ", ";
oss << "offset=" << self.offset << ")";
return oss.str();
})
.def_readwrite("attr_class", &whiteout::utils::VertexBuffer::Attribute::attr_class)
.def_readwrite("encoding", &whiteout::utils::VertexBuffer::Attribute::encoding)
.def_readwrite("component_count", &whiteout::utils::VertexBuffer::Attribute::component_count)
.def_readwrite("offset", &whiteout::utils::VertexBuffer::Attribute::offset)
;
py::class_<whiteout::utils::VertexBuffer>(m, "VertexBuffer")
.def(py::init<>())
.def_readwrite("data", &whiteout::utils::VertexBuffer::data)
.def_readwrite("layout", &whiteout::utils::VertexBuffer::layout)
.def_readwrite("vertex_stride", &whiteout::utils::VertexBuffer::vertex_stride)
.def("vertex_count", &whiteout::utils::VertexBuffer::vertexCount, R"doc(Get total number of vertices in the buffer)doc")
.def("vertex_size", &whiteout::utils::VertexBuffer::vertexSize, R"doc(Get per-vertex byte stride)doc")
.def("u_vs_num", &whiteout::utils::VertexBuffer::UVsNum, R"doc(Get number of UV layers present)doc")
.def("has_vertex_colors", &whiteout::utils::VertexBuffer::hasVertexColors, R"doc(Check if vertex color data is present)doc")
.def("get_positions", &whiteout::utils::VertexBuffer::getPositions, R"doc(Extract vertex positions (Vector3f, 12 bytes at offset 0))doc")
.def("get_normals", &whiteout::utils::VertexBuffer::getNormals, R"doc(Extract vertex normals (3 x i8 at offset 20, divided by 127.0))doc")
.def("get_tangents", &whiteout::utils::VertexBuffer::getTangents, R"doc(Extract tangent vectors (3 x i8 + sign byte at end of vertex))doc")
.def("get_u_vs", py::overload_cast<size_t>(&whiteout::utils::VertexBuffer::getUVs, py::const_), py::arg("which"), R"doc(Extract UV coordinates for a layer, decoded by the attribute's encoding: float and normalized encodings give the coordinate itself, and a raw integer one is StarCraft II's i16 fixed point (divided by 2048.0), which is the buffer this reader was first written for.)doc")
.def("get_u_vs", py::overload_cast<size_t, whiteout::f32, whiteout::f32>(&whiteout::utils::VertexBuffer::getUVs, py::const_), py::arg("which"), py::arg("uvMultiply"), py::arg("uvOffset"), R"doc(Extract UV coordinates using region-level scale/offset (REGN v5+) @param which UV layer index (0-based) @param uvMultiply UV scale factor (default 16.0 in REGN v5+) @param uvOffset UV offset (default 0.0 in REGN v5+) @return Vector of UV coordinates: float_uv = i16_uv * uvMultiply + uvOffset)doc")
.def("get_colors", py::overload_cast<>(&whiteout::utils::VertexBuffer::getColors, py::const_))
.def("get_colors", py::overload_cast<size_t>(&whiteout::utils::VertexBuffer::getColors, py::const_), py::arg("which"), R"doc(The @p which'th colour layer. Diablo III authors two — a tint and a baked occlusion mask — and reading only the first drops the second.)doc")
.def("get_binormals", &whiteout::utils::VertexBuffer::getBinormals, R"doc(The binormal layer, when the buffer declares one. Its own attribute rather than a sign bit on the tangent: D3 authors both vectors, and reconstructing one from the other assumes an orthonormal frame that content does not promise.)doc")
;
py::class_<whiteout::utils::VertexBufferBuilder>(m, "VertexBufferBuilder")
.def(py::init<>())
.def("declare_float_attribute",
[](whiteout::utils::VertexBufferBuilder& self, py::array_t<whiteout::f32, py::array::c_style | py::array::forcecast> __py_arr_0, size_t components, whiteout::utils::AttributeClass attr_class, whiteout::utils::AttributeEncoding encoding, size_t align) {
auto __buf_0 = __py_arr_0.request();
std::span<const whiteout::f32> data(
static_cast<const whiteout::f32*>(__buf_0.ptr),
static_cast<std::size_t>(__buf_0.size));
self.declareFloatAttribute(data, components, attr_class, encoding, align);
}, py::arg("data"), py::arg("components"), py::arg("attr_class"), py::arg("encoding"), py::arg("align") = size_t{}, R"doc(Non-template float-attribute entry point — accepts an already- flattened `f32` array as a `std::span` so the binding layer can aim straight at numpy buffers / `Float32Array` views with no intermediate copy (vertex_count = data.size() / components).)doc")
.def("declare_int_attribute",
[](whiteout::utils::VertexBufferBuilder& self, py::array_t<whiteout::u32, py::array::c_style | py::array::forcecast> __py_arr_0, size_t components, whiteout::utils::AttributeClass attr_class, whiteout::utils::AttributeEncoding encoding, size_t align) {
auto __buf_0 = __py_arr_0.request();
std::span<const whiteout::u32> data(
static_cast<const whiteout::u32*>(__buf_0.ptr),
static_cast<std::size_t>(__buf_0.size));
self.declareIntAttribute(data, components, attr_class, encoding, align);
}, py::arg("data"), py::arg("components"), py::arg("attr_class"), py::arg("encoding"), py::arg("align") = size_t{}, R"doc(Non-template integer-attribute entry point — accepts an already- flattened `u32` array. Smaller integer types (u8/u16/i8/i16/i32) are upcast at the call site. `std::span` keeps the boundary zero-copy.)doc")
.def("build", &whiteout::utils::VertexBufferBuilder::build, py::arg("pool") = nullptr, R"doc(Build the interleaved vertex buffer from all declared attributes. @param pool Optional WorkerPool for parallel encoding. When non-null and the vertex count is large enough, the vertex encoding loop is split into cache-friendly chunks across workers.)doc")
;
py::bind_vector<std::vector<whiteout::utils::VertexBuffer::Attribute>>(m, "VectorUtilsVertexBufferAttribute");
}