davidvgilmore commited on
Commit
c961ba6
·
verified ·
1 Parent(s): b5ace99

Upload hy3dgen/texgen/differentiable_renderer/mesh_processor.cpp with huggingface_hub

Browse files
hy3dgen/texgen/differentiable_renderer/mesh_processor.cpp ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <pybind11/pybind11.h>
2
+ #include <pybind11/numpy.h>
3
+ #include <pybind11/stl.h>
4
+ #include <vector>
5
+ #include <queue>
6
+ #include <cmath>
7
+ #include <algorithm>
8
+
9
+ namespace py = pybind11;
10
+ using namespace std;
11
+
12
+ std::pair<py::array_t<float>,
13
+ py::array_t<uint8_t>> meshVerticeInpaint_smooth(py::array_t<float> texture,
14
+ py::array_t<uint8_t> mask,
15
+ py::array_t<float> vtx_pos, py::array_t<float> vtx_uv,
16
+ py::array_t<int> pos_idx, py::array_t<int> uv_idx) {
17
+ auto texture_buf = texture.request();
18
+ auto mask_buf = mask.request();
19
+ auto vtx_pos_buf = vtx_pos.request();
20
+ auto vtx_uv_buf = vtx_uv.request();
21
+ auto pos_idx_buf = pos_idx.request();
22
+ auto uv_idx_buf = uv_idx.request();
23
+
24
+ int texture_height = texture_buf.shape[0];
25
+ int texture_width = texture_buf.shape[1];
26
+ int texture_channel = texture_buf.shape[2];
27
+ float* texture_ptr = static_cast<float*>(texture_buf.ptr);
28
+ uint8_t* mask_ptr = static_cast<uint8_t*>(mask_buf.ptr);
29
+
30
+ int vtx_num = vtx_pos_buf.shape[0];
31
+ float* vtx_pos_ptr = static_cast<float*>(vtx_pos_buf.ptr);
32
+ float* vtx_uv_ptr = static_cast<float*>(vtx_uv_buf.ptr);
33
+ int* pos_idx_ptr = static_cast<int*>(pos_idx_buf.ptr);
34
+ int* uv_idx_ptr = static_cast<int*>(uv_idx_buf.ptr);
35
+
36
+ vector<float> vtx_mask(vtx_num, 0.0f);
37
+ vector<vector<float>> vtx_color(vtx_num, vector<float>(texture_channel, 0.0f));
38
+ vector<int> uncolored_vtxs;
39
+
40
+ vector<vector<int>> G(vtx_num);
41
+
42
+ for (int i = 0; i < uv_idx_buf.shape[0]; ++i) {
43
+ for (int k = 0; k < 3; ++k) {
44
+ int vtx_uv_idx = uv_idx_ptr[i * 3 + k];
45
+ int vtx_idx = pos_idx_ptr[i * 3 + k];
46
+ int uv_v = round(vtx_uv_ptr[vtx_uv_idx * 2] * (texture_width - 1));
47
+ int uv_u = round((1.0 - vtx_uv_ptr[vtx_uv_idx * 2 + 1]) * (texture_height - 1));
48
+
49
+ if (mask_ptr[uv_u * texture_width + uv_v] > 0) {
50
+ vtx_mask[vtx_idx] = 1.0f;
51
+ for (int c = 0; c < texture_channel; ++c) {
52
+ vtx_color[vtx_idx][c] = texture_ptr[(uv_u * texture_width + uv_v) * texture_channel + c];
53
+ }
54
+ }else{
55
+ uncolored_vtxs.push_back(vtx_idx);
56
+ }
57
+
58
+ G[pos_idx_ptr[i * 3 + k]].push_back(pos_idx_ptr[i * 3 + (k + 1) % 3]);
59
+ }
60
+ }
61
+
62
+ int smooth_count = 2;
63
+ int last_uncolored_vtx_count = 0;
64
+ while (smooth_count>0) {
65
+ int uncolored_vtx_count = 0;
66
+
67
+ for (int vtx_idx : uncolored_vtxs) {
68
+
69
+ vector<float> sum_color(texture_channel, 0.0f);
70
+ float total_weight = 0.0f;
71
+
72
+ array<float, 3> vtx_0 = {vtx_pos_ptr[vtx_idx * 3],
73
+ vtx_pos_ptr[vtx_idx * 3 + 1], vtx_pos_ptr[vtx_idx * 3 + 2]};
74
+ for (int connected_idx : G[vtx_idx]) {
75
+ if (vtx_mask[connected_idx] > 0) {
76
+ array<float, 3> vtx1 = {vtx_pos_ptr[connected_idx * 3],
77
+ vtx_pos_ptr[connected_idx * 3 + 1], vtx_pos_ptr[connected_idx * 3 + 2]};
78
+ float dist_weight = 1.0f / max(sqrt(pow(vtx_0[0] - vtx1[0], 2) + pow(vtx_0[1] - vtx1[1], 2) + \
79
+ pow(vtx_0[2] - vtx1[2], 2)), 1E-4);
80
+ dist_weight = dist_weight * dist_weight;
81
+ for (int c = 0; c < texture_channel; ++c) {
82
+ sum_color[c] += vtx_color[connected_idx][c] * dist_weight;
83
+ }
84
+ total_weight += dist_weight;
85
+ }
86
+ }
87
+
88
+ if (total_weight > 0.0f) {
89
+ for (int c = 0; c < texture_channel; ++c) {
90
+ vtx_color[vtx_idx][c] = sum_color[c] / total_weight;
91
+ }
92
+ vtx_mask[vtx_idx] = 1.0f;
93
+ } else {
94
+ uncolored_vtx_count++;
95
+ }
96
+
97
+ }
98
+
99
+ if(last_uncolored_vtx_count==uncolored_vtx_count){
100
+ smooth_count--;
101
+ }else{
102
+ smooth_count++;
103
+ }
104
+ last_uncolored_vtx_count = uncolored_vtx_count;
105
+ }
106
+
107
+ // Create new arrays for the output
108
+ py::array_t<float> new_texture(texture_buf.size);
109
+ py::array_t<uint8_t> new_mask(mask_buf.size);
110
+
111
+ auto new_texture_buf = new_texture.request();
112
+ auto new_mask_buf = new_mask.request();
113
+
114
+ float* new_texture_ptr = static_cast<float*>(new_texture_buf.ptr);
115
+ uint8_t* new_mask_ptr = static_cast<uint8_t*>(new_mask_buf.ptr);
116
+ // Copy original texture and mask to new arrays
117
+ std::copy(texture_ptr, texture_ptr + texture_buf.size, new_texture_ptr);
118
+ std::copy(mask_ptr, mask_ptr + mask_buf.size, new_mask_ptr);
119
+
120
+ for (int face_idx = 0; face_idx < uv_idx_buf.shape[0]; ++face_idx) {
121
+ for (int k = 0; k < 3; ++k) {
122
+ int vtx_uv_idx = uv_idx_ptr[face_idx * 3 + k];
123
+ int vtx_idx = pos_idx_ptr[face_idx * 3 + k];
124
+
125
+ if (vtx_mask[vtx_idx] == 1.0f) {
126
+ int uv_v = round(vtx_uv_ptr[vtx_uv_idx * 2] * (texture_width - 1));
127
+ int uv_u = round((1.0 - vtx_uv_ptr[vtx_uv_idx * 2 + 1]) * (texture_height - 1));
128
+
129
+ for (int c = 0; c < texture_channel; ++c) {
130
+ new_texture_ptr[(uv_u * texture_width + uv_v) * texture_channel + c] = vtx_color[vtx_idx][c];
131
+ }
132
+ new_mask_ptr[uv_u * texture_width + uv_v] = 255;
133
+ }
134
+ }
135
+ }
136
+
137
+ // Reshape the new arrays to match the original texture and mask shapes
138
+ new_texture.resize({texture_height, texture_width, 3});
139
+ new_mask.resize({texture_height, texture_width});
140
+ return std::make_pair(new_texture, new_mask);
141
+ }
142
+
143
+
144
+ std::pair<py::array_t<float>, py::array_t<uint8_t>> meshVerticeInpaint(py::array_t<float> texture,
145
+ py::array_t<uint8_t> mask,
146
+ py::array_t<float> vtx_pos, py::array_t<float> vtx_uv,
147
+ py::array_t<int> pos_idx, py::array_t<int> uv_idx, const std::string& method = "smooth") {
148
+ if (method == "smooth") {
149
+ return meshVerticeInpaint_smooth(texture, mask, vtx_pos, vtx_uv, pos_idx, uv_idx);
150
+ } else {
151
+ throw std::invalid_argument("Invalid method. Use 'smooth' or 'forward'.");
152
+ }
153
+ }
154
+
155
+ PYBIND11_MODULE(mesh_processor, m) {
156
+ m.def("meshVerticeInpaint", &meshVerticeInpaint, "A function to process mesh",
157
+ py::arg("texture"), py::arg("mask"),
158
+ py::arg("vtx_pos"), py::arg("vtx_uv"),
159
+ py::arg("pos_idx"), py::arg("uv_idx"),
160
+ py::arg("method") = "smooth");
161
+ }