21 namespace trianglemesh {
31 const int64_t* triangle_ptr = triangles_d.
GetDataPtr<int64_t>();
32 const scalar_t* triangle_normals_ptr =
34 scalar_t* vertex_normals_ptr = vertex_normals.
GetDataPtr<scalar_t>();
36 for (int64_t i = 0; i < n; ++i) {
38 int64_t triangle_id1 = triangle_ptr[idx];
39 int64_t triangle_id2 = triangle_ptr[idx + 1];
40 int64_t triangle_id3 = triangle_ptr[idx + 2];
42 scalar_t n1 = triangle_normals_ptr[idx];
43 scalar_t n2 = triangle_normals_ptr[idx + 1];
44 scalar_t n3 = triangle_normals_ptr[idx + 2];
46 vertex_normals_ptr[3 * triangle_id1] += n1;
47 vertex_normals_ptr[3 * triangle_id1 + 1] += n2;
48 vertex_normals_ptr[3 * triangle_id1 + 2] += n3;
49 vertex_normals_ptr[3 * triangle_id2] += n1;
50 vertex_normals_ptr[3 * triangle_id2 + 1] += n2;
51 vertex_normals_ptr[3 * triangle_id2 + 2] += n3;
52 vertex_normals_ptr[3 * triangle_id3] += n1;
53 vertex_normals_ptr[3 * triangle_id3 + 1] += n2;
54 vertex_normals_ptr[3 * triangle_id3 + 2] += n3;
60 void mix_3x3(T* out,
const T* a,
const T* b,
const T* c,
float wts[3]) {
61 out[0] = wts[0] * a[0] + wts[1] * b[0] + wts[2] * c[0];
62 out[1] = wts[0] * a[1] + wts[1] * b[1] + wts[2] * c[1];
63 out[2] = wts[0] * a[2] + wts[1] * b[2] + wts[2] * c[2];
85 size_t number_of_points) {
88 {
static_cast<int64_t
>(number_of_points), 3}, vertices.
GetDtype());
90 bool use_vert_normal = vertex_normals.
NumElements() > 0,
91 use_triangle_normal = triangle_normals.
NumElements() > 0,
94 if (use_vert_normal || use_triangle_normal) {
96 {
static_cast<int64_t
>(number_of_points), 3},
points.GetDtype());
98 if (use_albedo || use_vert_colors) {
102 const size_t tex_width = use_albedo ? albedo.
GetShape(1) : 0,
103 tex_height = use_albedo ? albedo.
GetShape(0) : 0;
106 const int_t* p_triangles = triangles.GetDataPtr<int_t>();
107 const scalar_t* p_vertices = vertices.GetDataPtr<scalar_t>();
108 const scalar_t* p_vert_normals =
109 use_vert_normal ? vertex_normals.GetDataPtr<scalar_t>()
111 const float* p_vert_colors =
112 use_vert_colors ? vertex_colors.GetDataPtr<float>()
114 const scalar_t* p_tri_normals =
116 ? triangle_normals.GetDataPtr<scalar_t>()
118 const scalar_t* p_tri_uvs =
119 use_albedo ? texture_uvs.GetDataPtr<scalar_t>()
121 const float* p_albedo =
122 use_albedo ? albedo.GetDataPtr<float>() : nullptr;
124 scalar_t* p_points = points.GetDataPtr<scalar_t>();
125 scalar_t* p_normals = (use_vert_normal || use_triangle_normal)
126 ? normals.GetDataPtr<scalar_t>()
128 float* p_colors = (use_albedo || use_vert_colors)
129 ? colors.GetDataPtr<float>()
132 utility::random::DiscreteGenerator<size_t>
133 triangle_index_generator(
134 triangle_areas.GetDataPtr<scalar_t>(),
135 triangle_areas.GetDataPtr<scalar_t>() +
136 triangles.GetLength());
138 for (size_t point_idx = 0; point_idx < number_of_points;
139 ++point_idx, p_points += 3) {
140 float r1 = uniform_generator();
141 float r2 = uniform_generator();
142 float wts[3] = {1 - std::sqrt(r1), std::sqrt(r1) * (1 - r2),
144 size_t tidx = triangle_index_generator();
145 int_t vert_idx[3] = {p_triangles[3 * tidx + 0],
146 p_triangles[3 * tidx + 1],
147 p_triangles[3 * tidx + 2]};
149 mix_3x3(p_points, p_vertices + 3 * vert_idx[0],
150 p_vertices + 3 * vert_idx[1],
151 p_vertices + 3 * vert_idx[2], wts);
153 if (use_vert_normal) {
154 mix_3x3(p_normals, p_vert_normals + 3 * vert_idx[0],
155 p_vert_normals + 3 * vert_idx[1],
156 p_vert_normals + 3 * vert_idx[2], wts);
158 } else if (use_triangle_normal) {
159 std::copy(p_tri_normals + 3 * tidx,
160 p_tri_normals + 3 * (tidx + 1), p_normals);
166 float u = wts[0] * p_tri_uvs[6 * tidx] +
167 wts[1] * p_tri_uvs[6 * tidx + 2] +
168 wts[2] * p_tri_uvs[6 * tidx + 4];
169 float v = wts[0] * p_tri_uvs[6 * tidx + 1] +
170 wts[1] * p_tri_uvs[6 * tidx + 3] +
171 wts[2] * p_tri_uvs[6 * tidx + 5];
172 size_t x = u * tex_width, y = v * tex_height;
173 std::copy(p_albedo + 3 * (y * tex_width + x),
174 p_albedo + 3 * (y * tex_width + x + 1),
178 else if (use_vert_colors) {
179 mix_3x3(p_colors, p_vert_colors + 3 * vert_idx[0],
180 p_vert_colors + 3 * vert_idx[1],
181 p_vert_colors + 3 * vert_idx[2], wts);
#define DISPATCH_DTYPE_TO_TEMPLATE(DTYPE,...)
#define DISPATCH_FLOAT_INT_DTYPE_TO_TEMPLATE(FDTYPE, IDTYPE,...)
int64_t GetLength() const
int64_t NumElements() const
static Tensor Empty(const SizeVector &shape, Dtype dtype, const Device &device=Device("CPU:0"))
Create a tensor with uninitialized values.
SizeVector GetShape() const
Tensor To(Dtype dtype, bool copy=false) const
void mix_3x3(T *out, const T *a, const T *b, const T *c, float wts[3])
void ComputeVertexNormalsCPU(const core::Tensor &triangles, const core::Tensor &triangle_normals, core::Tensor &vertex_normals)
std::array< core::Tensor, 3 > SamplePointsUniformlyCPU(const core::Tensor &triangles, const core::Tensor &vertices, const core::Tensor &triangle_areas, const core::Tensor &vertex_normals, const core::Tensor &vertex_colors, const core::Tensor &triangle_normals, const core::Tensor &texture_uvs, const core::Tensor &albedo, size_t number_of_points)
template void mix_3x3< float >(float *out, const float *a, const float *b, const float *c, float wts[3])
Generic file read and write utility for python interface.