Skip to content

Commit

Permalink
Moved shape sampling
Browse files Browse the repository at this point in the history
  • Loading branch information
xelatihy committed Jan 29, 2024
1 parent 12d9029 commit 925414c
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 221 deletions.
145 changes: 144 additions & 1 deletion libs/yocto/yocto_sampling.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,43 @@ inline float sample_discrete_pdf(const vector<float>& cdf, int idx);

} // namespace yocto

// -----------------------------------------------------------------------------
// SHAPE SAMPLING
// -----------------------------------------------------------------------------
namespace yocto {

// Pick a point in a point set uniformly.
inline int sample_points(int npoints, float re);
inline int sample_points(const vector<float>& cdf, float re);
inline vector<float> sample_points_cdf(int npoints);
inline void sample_points_cdf(vector<float>& cdf, int npoints);

// Pick a point on lines uniformly.
inline pair<int, float> sample_lines(
const vector<float>& cdf, float re, float ru);
inline vector<float> sample_lines_cdf(
const vector<vec2i>& lines, const vector<vec3f>& positions);
inline void sample_lines_cdf(vector<float>& cdf, const vector<vec2i>& lines,
const vector<vec3f>& positions);

// Pick a point on a triangle mesh uniformly.
inline pair<int, vec2f> sample_triangles(
const vector<float>& cdf, float re, vec2f ruv);
inline vector<float> sample_triangles_cdf(
const vector<vec3i>& triangles, const vector<vec3f>& positions);
inline void sample_triangles_cdf(vector<float>& cdf,
const vector<vec3i>& triangles, const vector<vec3f>& positions);

// Pick a point on a quad mesh uniformly.
inline pair<int, vec2f> sample_quads(
const vector<float>& cdf, float re, vec2f ruv);
inline vector<float> sample_quads_cdf(
const vector<vec4i>& quads, const vector<vec3f>& positions);
inline void sample_quads_cdf(vector<float>& cdf, const vector<vec4i>& quads,
const vector<vec3f>& positions);

} // namespace yocto

// -----------------------------------------------------------------------------
//
//
Expand Down Expand Up @@ -254,7 +291,7 @@ inline void shuffle(vector<T>& vals, rng_state& rng) {
} // namespace yocto

// -----------------------------------------------------------------------------
// IMPLEMENTATION OF MONETACARLO SAMPLING FUNCTIONS
// IMPLEMENTATION OF MONTECARLO SAMPLING FUNCTIONS
// -----------------------------------------------------------------------------
namespace yocto {

Expand Down Expand Up @@ -404,6 +441,112 @@ inline float sample_discrete_pdf(const vector<float>& cdf, int idx) {

} // namespace yocto

// -----------------------------------------------------------------------------
// IMPLEMENTATION OF SHAPE SAMPLING
// -----------------------------------------------------------------------------
namespace yocto {

// Pick a point in a point set uniformly.
inline int sample_points(int npoints, float re) {
return sample_uniform(npoints, re);
}
inline int sample_points(const vector<float>& cdf, float re) {
return sample_discrete(cdf, re);
}
inline vector<float> sample_points_cdf(int npoints) {
auto cdf = vector<float>(npoints);
for (auto i : range(cdf.size())) cdf[i] = 1 + (i != 0 ? cdf[i - 1] : 0);
return cdf;
}
inline void sample_points_cdf(vector<float>& cdf, int npoints) {
for (auto i : range(cdf.size())) cdf[i] = 1 + (i != 0 ? cdf[i - 1] : 0);
}

// Pick a point on lines uniformly.
inline pair<int, float> sample_lines(
const vector<float>& cdf, float re, float ru) {
return {sample_discrete(cdf, re), ru};
}
inline vector<float> sample_lines_cdf(
const vector<vec2i>& lines, const vector<vec3f>& positions) {
auto cdf = vector<float>(lines.size());
for (auto i : range(cdf.size())) {
auto& l = lines[i];
auto w = line_length(positions[l.x], positions[l.y]);
cdf[i] = w + (i != 0 ? cdf[i - 1] : 0);
}
return cdf;
}
inline void sample_lines_cdf(vector<float>& cdf, const vector<vec2i>& lines,
const vector<vec3f>& positions) {
for (auto i : range(cdf.size())) {
auto& l = lines[i];
auto w = line_length(positions[l.x], positions[l.y]);
cdf[i] = w + (i != 0 ? cdf[i - 1] : 0);
}
}

// Pick a point on a triangle mesh uniformly.
inline pair<int, vec2f> sample_triangles(
const vector<float>& cdf, float re, vec2f ruv) {
return {sample_discrete(cdf, re), sample_triangle(ruv)};
}
inline vector<float> sample_triangles_cdf(
const vector<vec3i>& triangles, const vector<vec3f>& positions) {
auto cdf = vector<float>(triangles.size());
for (auto i : range(cdf.size())) {
auto& t = triangles[i];
auto w = triangle_area(positions[t.x], positions[t.y], positions[t.z]);
cdf[i] = w + (i != 0 ? cdf[i - 1] : 0);
}
return cdf;
}
inline void sample_triangles_cdf(vector<float>& cdf,
const vector<vec3i>& triangles, const vector<vec3f>& positions) {
for (auto i : range(cdf.size())) {
auto& t = triangles[i];
auto w = triangle_area(positions[t.x], positions[t.y], positions[t.z]);
cdf[i] = w + (i != 0 ? cdf[i - 1] : 0);
}
}

// Pick a point on a quad mesh uniformly.
inline pair<int, vec2f> sample_quads(
const vector<float>& cdf, float re, vec2f ruv) {
return {sample_discrete(cdf, re), ruv};
}
inline pair<int, vec2f> sample_quads(
const vector<vec4i>& quads, const vector<float>& cdf, float re, vec2f ruv) {
auto element = sample_discrete(cdf, re);
if (quads[element].z == quads[element].w) {
return {element, sample_triangle(ruv)};
} else {
return {element, ruv};
}
}
inline vector<float> sample_quads_cdf(
const vector<vec4i>& quads, const vector<vec3f>& positions) {
auto cdf = vector<float>(quads.size());
for (auto i : range(cdf.size())) {
auto& q = quads[i];
auto w = quad_area(
positions[q.x], positions[q.y], positions[q.z], positions[q.w]);
cdf[i] = w + (i ? cdf[i - 1] : 0);
}
return cdf;
}
inline void sample_quads_cdf(vector<float>& cdf, const vector<vec4i>& quads,
const vector<vec3f>& positions) {
for (auto i : range(cdf.size())) {
auto& q = quads[i];
auto w = quad_area(
positions[q.x], positions[q.y], positions[q.z], positions[q.w]);
cdf[i] = w + (i ? cdf[i - 1] : 0);
}
}

} // namespace yocto

// -----------------------------------------------------------------------------
// CUDA SUPPORT
// -----------------------------------------------------------------------------
Expand Down
172 changes: 0 additions & 172 deletions libs/yocto/yocto_shape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1742,178 +1742,6 @@ void split_facevarying(vector<vec4i>& split_quads,

} // namespace yocto

// -----------------------------------------------------------------------------
// IMPLEMENTATION OF SHAPE SAMPLING
// -----------------------------------------------------------------------------
namespace yocto {

// Pick a point in a point set uniformly.
int sample_points(int npoints, float re) { return sample_uniform(npoints, re); }
int sample_points(const vector<float>& cdf, float re) {
return sample_discrete(cdf, re);
}
vector<float> sample_points_cdf(int npoints) {
auto cdf = vector<float>(npoints);
for (auto i : range(cdf.size())) cdf[i] = 1 + (i != 0 ? cdf[i - 1] : 0);
return cdf;
}
void sample_points_cdf(vector<float>& cdf, int npoints) {
for (auto i : range(cdf.size())) cdf[i] = 1 + (i != 0 ? cdf[i - 1] : 0);
}

// Pick a point on lines uniformly.
pair<int, float> sample_lines(const vector<float>& cdf, float re, float ru) {
return {sample_discrete(cdf, re), ru};
}
vector<float> sample_lines_cdf(
const vector<vec2i>& lines, const vector<vec3f>& positions) {
auto cdf = vector<float>(lines.size());
for (auto i : range(cdf.size())) {
auto& l = lines[i];
auto w = line_length(positions[l.x], positions[l.y]);
cdf[i] = w + (i != 0 ? cdf[i - 1] : 0);
}
return cdf;
}
void sample_lines_cdf(vector<float>& cdf, const vector<vec2i>& lines,
const vector<vec3f>& positions) {
for (auto i : range(cdf.size())) {
auto& l = lines[i];
auto w = line_length(positions[l.x], positions[l.y]);
cdf[i] = w + (i != 0 ? cdf[i - 1] : 0);
}
}

// Pick a point on a triangle mesh uniformly.
pair<int, vec2f> sample_triangles(
const vector<float>& cdf, float re, vec2f ruv) {
return {sample_discrete(cdf, re), sample_triangle(ruv)};
}
vector<float> sample_triangles_cdf(
const vector<vec3i>& triangles, const vector<vec3f>& positions) {
auto cdf = vector<float>(triangles.size());
for (auto i : range(cdf.size())) {
auto& t = triangles[i];
auto w = triangle_area(positions[t.x], positions[t.y], positions[t.z]);
cdf[i] = w + (i != 0 ? cdf[i - 1] : 0);
}
return cdf;
}
void sample_triangles_cdf(vector<float>& cdf, const vector<vec3i>& triangles,
const vector<vec3f>& positions) {
for (auto i : range(cdf.size())) {
auto& t = triangles[i];
auto w = triangle_area(positions[t.x], positions[t.y], positions[t.z]);
cdf[i] = w + (i != 0 ? cdf[i - 1] : 0);
}
}

// Pick a point on a quad mesh uniformly.
pair<int, vec2f> sample_quads(const vector<float>& cdf, float re, vec2f ruv) {
return {sample_discrete(cdf, re), ruv};
}
pair<int, vec2f> sample_quads(
const vector<vec4i>& quads, const vector<float>& cdf, float re, vec2f ruv) {
auto element = sample_discrete(cdf, re);
if (quads[element].z == quads[element].w) {
return {element, sample_triangle(ruv)};
} else {
return {element, ruv};
}
}
vector<float> sample_quads_cdf(
const vector<vec4i>& quads, const vector<vec3f>& positions) {
auto cdf = vector<float>(quads.size());
for (auto i : range(cdf.size())) {
auto& q = quads[i];
auto w = quad_area(
positions[q.x], positions[q.y], positions[q.z], positions[q.w]);
cdf[i] = w + (i ? cdf[i - 1] : 0);
}
return cdf;
}
void sample_quads_cdf(vector<float>& cdf, const vector<vec4i>& quads,
const vector<vec3f>& positions) {
for (auto i : range(cdf.size())) {
auto& q = quads[i];
auto w = quad_area(
positions[q.x], positions[q.y], positions[q.z], positions[q.w]);
cdf[i] = w + (i ? cdf[i - 1] : 0);
}
}

// Samples a set of points over a triangle mesh uniformly. The rng function
// takes the point index and returns vec3f numbers uniform directibuted in
// [0,1]^3. unorm and texcoord are optional.
void sample_triangles(vector<vec3f>& sampled_positions,
vector<vec3f>& sampled_normals, vector<vec2f>& sampled_texcoords,
const vector<vec3i>& triangles, const vector<vec3f>& positions,
const vector<vec3f>& normals, const vector<vec2f>& texcoords, int npoints,
int seed) {
sampled_positions.resize(npoints);
sampled_normals.resize(npoints);
sampled_texcoords.resize(npoints);
auto cdf = sample_triangles_cdf(triangles, positions);
auto rng = make_rng(seed);
for (auto i : range(npoints)) {
auto sample = sample_triangles(cdf, rand1f(rng), rand2f(rng));
auto& t = triangles[sample.first];
auto uv = sample.second;
sampled_positions[i] = interpolate_triangle(
positions[t.x], positions[t.y], positions[t.z], uv);
if (!sampled_normals.empty()) {
sampled_normals[i] = normalize(
interpolate_triangle(normals[t.x], normals[t.y], normals[t.z], uv));
} else {
sampled_normals[i] = triangle_normal(
positions[t.x], positions[t.y], positions[t.z]);
}
if (!sampled_texcoords.empty()) {
sampled_texcoords[i] = interpolate_triangle(
texcoords[t.x], texcoords[t.y], texcoords[t.z], uv);
} else {
sampled_texcoords[i] = vec2f{0, 0};
}
}
}

// Samples a set of points over a triangle mesh uniformly. The rng function
// takes the point index and returns vec3f numbers uniform directibuted in
// [0,1]^3. unorm and texcoord are optional.
void sample_quads(vector<vec3f>& sampled_positions,
vector<vec3f>& sampled_normals, vector<vec2f>& sampled_texcoords,
const vector<vec4i>& quads, const vector<vec3f>& positions,
const vector<vec3f>& normals, const vector<vec2f>& texcoords, int npoints,
int seed) {
sampled_positions.resize(npoints);
sampled_normals.resize(npoints);
sampled_texcoords.resize(npoints);
auto cdf = sample_quads_cdf(quads, positions);
auto rng = make_rng(seed);
for (auto i : range(npoints)) {
auto sample = sample_quads(cdf, rand1f(rng), rand2f(rng));
auto& q = quads[sample.first];
auto uv = sample.second;
sampled_positions[i] = interpolate_quad(
positions[q.x], positions[q.y], positions[q.z], positions[q.w], uv);
if (!sampled_normals.empty()) {
sampled_normals[i] = normalize(interpolate_quad(
normals[q.x], normals[q.y], normals[q.z], normals[q.w], uv));
} else {
sampled_normals[i] = quad_normal(
positions[q.x], positions[q.y], positions[q.z], positions[q.w]);
}
if (!sampled_texcoords.empty()) {
sampled_texcoords[i] = interpolate_quad(
texcoords[q.x], texcoords[q.y], texcoords[q.z], texcoords[q.w], uv);
} else {
sampled_texcoords[i] = vec2f{0, 0};
}
}
}

} // namespace yocto

// -----------------------------------------------------------------------------
// SHAPE DATA
// -----------------------------------------------------------------------------
Expand Down
48 changes: 0 additions & 48 deletions libs/yocto/yocto_shape.h
Original file line number Diff line number Diff line change
Expand Up @@ -419,54 +419,6 @@ void split_facevarying(vector<vec4i>& split_quads,

} // namespace yocto

// -----------------------------------------------------------------------------
// SHAPE SAMPLING
// -----------------------------------------------------------------------------
namespace yocto {

// Pick a point in a point set uniformly.
int sample_points(int npoints, float re);
int sample_points(const vector<float>& cdf, float re);
vector<float> sample_points_cdf(int npoints);
void sample_points_cdf(vector<float>& cdf, int npoints);

// Pick a point on lines uniformly.
pair<int, float> sample_lines(const vector<float>& cdf, float re, float ru);
vector<float> sample_lines_cdf(
const vector<vec2i>& lines, const vector<vec3f>& positions);
void sample_lines_cdf(vector<float>& cdf, const vector<vec2i>& lines,
const vector<vec3f>& positions);

// Pick a point on a triangle mesh uniformly.
pair<int, vec2f> sample_triangles(
const vector<float>& cdf, float re, vec2f ruv);
vector<float> sample_triangles_cdf(
const vector<vec3i>& triangles, const vector<vec3f>& positions);
void sample_triangles_cdf(vector<float>& cdf, const vector<vec3i>& triangles,
const vector<vec3f>& positions);

// Pick a point on a quad mesh uniformly.
pair<int, vec2f> sample_quads(const vector<float>& cdf, float re, vec2f ruv);
vector<float> sample_quads_cdf(
const vector<vec4i>& quads, const vector<vec3f>& positions);
void sample_quads_cdf(vector<float>& cdf, const vector<vec4i>& quads,
const vector<vec3f>& positions);

// Samples a set of points over a triangle/quad mesh uniformly. Returns pos,
// norm and texcoord of the sampled points.
void sample_triangles(vector<vec3f>& sampled_positions,
vector<vec3f>& sampled_normals, vector<vec2f>& sampled_texcoords,
const vector<vec3i>& triangles, const vector<vec3f>& positions,
const vector<vec3f>& normals, const vector<vec2f>& texcoords, int npoints,
int seed = 7);
void sample_quads(vector<vec3f>& sampled_positions,
vector<vec3f>& sampled_normals, vector<vec2f>& sampled_texcoords,
const vector<vec4i>& quads, const vector<vec3f>& positions,
const vector<vec3f>& normals, const vector<vec2f>& texcoords, int npoints,
int seed = 7);

} // namespace yocto

// -----------------------------------------------------------------------------
//
//
Expand Down

0 comments on commit 925414c

Please sign in to comment.