Skip to content

Commit be9b47e

Browse files
authored
Merge pull request #25 from mworchel/vertex-assignments-and-chart-arrays
Vertex assignments and chart array access
2 parents 20b2018 + a801236 commit be9b47e

3 files changed

Lines changed: 100 additions & 2 deletions

File tree

src/atlas.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,66 @@ MeshResult Atlas::getMesh(std::uint32_t index) const
176176
return std::make_tuple(mapping, indices, uvs);
177177
}
178178

179+
VertexAssignment Atlas::getMeshVertexAssignment(std::uint32_t meshIndex) const
180+
{
181+
if (meshIndex >= m_atlas->meshCount)
182+
{
183+
throw std::out_of_range("Mesh index " + std::to_string(meshIndex) + " out of bounds for atlas with " + std::to_string(m_atlas->meshCount) + " meshes.");
184+
}
185+
186+
auto const& mesh = m_atlas->meshes[meshIndex];
187+
188+
py::array_t<std::uint32_t> atlasIndex(py::array::ShapeContainer{mesh.vertexCount});
189+
py::array_t<std::uint32_t> chartIndex(py::array::ShapeContainer{mesh.vertexCount});
190+
auto atlasIndex_ = atlasIndex.mutable_unchecked<1>();
191+
auto chartIndex_ = chartIndex.mutable_unchecked<1>();
192+
for (size_t v = 0; v < static_cast<size_t>(mesh.vertexCount); ++v)
193+
{
194+
auto const& vertex = mesh.vertexArray[v];
195+
atlasIndex_(v) = vertex.atlasIndex;
196+
chartIndex_(v) = vertex.chartIndex;
197+
}
198+
199+
return std::make_tuple(atlasIndex, chartIndex);
200+
}
201+
202+
uint32_t Atlas::getMeshChartCount(std::uint32_t meshIndex) const
203+
{
204+
if (meshIndex >= m_atlas->meshCount)
205+
throw std::out_of_range("Mesh index " + std::to_string(meshIndex) + " out of bounds for atlas with " + std::to_string(m_atlas->meshCount) + " meshes.");
206+
207+
auto const& mesh = m_atlas->meshes[meshIndex];
208+
209+
return mesh.chartCount;
210+
}
211+
212+
Chart Atlas::getMeshChart(std::uint32_t meshIndex, std::uint32_t chartIndex) const
213+
{
214+
if (meshIndex >= m_atlas->meshCount)
215+
throw std::out_of_range("Mesh index " + std::to_string(meshIndex) + " out of bounds for atlas with " + std::to_string(m_atlas->meshCount) + " meshes.");
216+
217+
auto const& mesh = m_atlas->meshes[meshIndex];
218+
219+
if (chartIndex >= mesh.chartCount)
220+
throw std::out_of_range("Chart index " + std::to_string(chartIndex) + " out of bounds for mesh with " + std::to_string(mesh.chartCount) + " charts.");
221+
222+
xatlas::Chart& chart = mesh.chartArray[chartIndex];
223+
py::array_t<std::uint32_t> faces(py::array::ShapeContainer{chart.faceCount});
224+
auto faces_ = faces.mutable_unchecked<1>();
225+
for (size_t i = 0; i < static_cast<size_t>(chart.faceCount); ++i)
226+
{
227+
faces_(i) = chart.faceArray[i];
228+
}
229+
230+
Chart chart_;
231+
chart_.faces = faces;
232+
chart_.atlasIndex = chart.atlasIndex;
233+
chart_.type = chart.type;
234+
chart_.material = chart.material;
235+
236+
return chart_;
237+
}
238+
179239
float Atlas::getUtilization(std::uint32_t index) const
180240
{
181241
if (index >= m_atlas->atlasCount)
@@ -259,12 +319,21 @@ py::array_t<std::uint8_t> Atlas::getChartImage(std::uint32_t index) const
259319

260320
void Atlas::bind(py::module& m)
261321
{
322+
py::class_<Chart>(m, "Chart")
323+
.def_property_readonly("faces", [](Chart const& self) { return self.faces; })
324+
.def_property_readonly("atlas_index", [](Chart const& self) { return self.atlasIndex; })
325+
.def_property_readonly("type", [](Chart const& self) { return self.type; })
326+
.def_property_readonly("material", [](Chart const& self) { return self.material; });
327+
262328
py::class_<Atlas>(m, "Atlas")
263329
.def(py::init<>())
264330
.def("add_mesh", &Atlas::addMesh, py::arg("positions"), py::arg("indices"), py::arg("normals") = std::nullopt, py::arg("uvs") = std::nullopt)
265331
.def("add_uv_mesh", &Atlas::addUvMesh, py::arg("uvs"), py::arg("indices"), py::arg("face_materials") = std::nullopt)
266332
.def("generate", &Atlas::generate, py::arg("chart_options") = xatlas::ChartOptions(), py::arg("pack_options") = xatlas::PackOptions(), py::arg("verbose") = false)
267333
.def("get_mesh", &Atlas::getMesh, py::arg("mesh_index"))
334+
.def("get_mesh_vertex_assignment", &Atlas::getMeshVertexAssignment, py::arg("mesh_index"))
335+
.def("get_mesh_chart_count", &Atlas::getMeshChartCount, py::arg("mesh_index"))
336+
.def("get_mesh_chart", &Atlas::getMeshChart, py::arg("mesh_index"), py::arg("chart_index"))
268337
.def("get_utilization", &Atlas::getUtilization, py::arg("atlas_index"))
269338
.def("get_chart_image", &Atlas::getChartImage, py::arg("atlas_index"))
270339
.def_property_readonly("atlas_count", [](Atlas const& self) { return self.m_atlas->atlasCount; })

src/atlas.hpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,24 @@
3434
#include <optional>
3535
#include <tuple>
3636

37-
using MeshResult = std::tuple<pybind11::array_t<std::uint32_t>, pybind11::array_t<std::uint32_t>, pybind11::array_t<float>>;
37+
using MeshResult = std::tuple<
38+
pybind11::array_t<std::uint32_t>,
39+
pybind11::array_t<std::uint32_t>,
40+
pybind11::array_t<float>
41+
>;
42+
43+
using VertexAssignment = std::tuple<
44+
pybind11::array_t<std::uint32_t>, // Atlas index
45+
pybind11::array_t<std::uint32_t> // Chart index
46+
>;
47+
48+
struct Chart
49+
{
50+
pybind11::array_t<std::uint32_t> faces;
51+
uint32_t atlasIndex; // Sub-atlas index.
52+
xatlas::ChartType type;
53+
uint32_t material;
54+
};
3855

3956
class Atlas
4057
{
@@ -56,6 +73,12 @@ class Atlas
5673

5774
MeshResult getMesh(std::uint32_t index) const;
5875

76+
VertexAssignment getMeshVertexAssignment(std::uint32_t meshIndex) const;
77+
78+
uint32_t getMeshChartCount(std::uint32_t meshIndex) const;
79+
80+
Chart getMeshChart(std::uint32_t meshIndex, std::uint32_t chartIndex) const;
81+
5982
float getUtilization(std::uint32_t index) const;
6083

6184
pybind11::array_t<std::uint8_t> getChartImage(std::uint32_t index) const;

src/module.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,13 @@ void exportObj(std::string const& path,
139139

140140
PYBIND11_MODULE(xatlas, m)
141141
{
142-
// Bindings
142+
py::enum_<xatlas::ChartType>(m, "ChartType")
143+
.value("Planar", xatlas::ChartType::Planar)
144+
.value("Ortho", xatlas::ChartType::Ortho)
145+
.value("LSCM", xatlas::ChartType::LSCM)
146+
.value("Piecewise", xatlas::ChartType::Piecewise)
147+
.value("Invalid", xatlas::ChartType::Invalid);
148+
143149
ChartOptions::bind(m);
144150
PackOptions::bind(m);
145151
Atlas::bind(m);

0 commit comments

Comments
 (0)