Skip to content

Commit

Permalink
More moved code from shape
Browse files Browse the repository at this point in the history
  • Loading branch information
xelatihy committed Jan 30, 2024
1 parent 925414c commit 8ef2504
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 302 deletions.
143 changes: 143 additions & 0 deletions libs/yocto/yocto_modeling.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

#include <array>
#include <tuple>
#include <unordered_map>
#include <utility>
#include <vector>

Expand All @@ -55,6 +56,7 @@ namespace yocto {
using std::array;
using std::pair;
using std::tuple;
using std::unordered_map;
using std::vector;

} // namespace yocto
Expand Down Expand Up @@ -419,6 +421,76 @@ inline float turbulence_noise(Noise&& base_noise, vec2f position, int num = 8);

} // namespace yocto

// -----------------------------------------------------------------------------
// VECTOR HASHING
// -----------------------------------------------------------------------------
namespace std {

// Hash functor for vector for use with hash_map
template <>
struct hash<yocto::vec2i> {
size_t operator()(const yocto::vec2i& v) const {
static const auto hasher = std::hash<int>();
auto h = (size_t)0;
h ^= hasher(v.x) + 0x9e3779b9 + (h << 6) + (h >> 2);
h ^= hasher(v.y) + 0x9e3779b9 + (h << 6) + (h >> 2);
return h;
}
};
template <>
struct hash<yocto::vec3i> {
size_t operator()(const yocto::vec3i& v) const {
static const auto hasher = std::hash<int>();
auto h = (size_t)0;
h ^= hasher(v.x) + 0x9e3779b9 + (h << 6) + (h >> 2);
h ^= hasher(v.y) + 0x9e3779b9 + (h << 6) + (h >> 2);
h ^= hasher(v.z) + 0x9e3779b9 + (h << 6) + (h >> 2);
return h;
}
};
template <>
struct hash<yocto::vec4i> {
size_t operator()(const yocto::vec4i& v) const {
static const auto hasher = std::hash<int>();
auto h = (size_t)0;
h ^= hasher(v.x) + 0x9e3779b9 + (h << 6) + (h >> 2);
h ^= hasher(v.y) + 0x9e3779b9 + (h << 6) + (h >> 2);
h ^= hasher(v.z) + 0x9e3779b9 + (h << 6) + (h >> 2);
h ^= hasher(v.w) + 0x9e3779b9 + (h << 6) + (h >> 2);
return h;
}
};

} // namespace std

// -----------------------------------------------------------------------------
// HASH GRID AND NEAREST NEIGHBORS
// -----------------------------------------------------------------------------
namespace yocto {

// A sparse grid of cells, containing list of points. Cells are stored in
// a dictionary to get sparsity. Helpful for nearest neighbor lookups.
struct hash_grid {
float cell_size = 0;
float cell_inv_size = 0;
vector<vec3f> positions = {};
unordered_map<vec3i, vector<int>> cells = {};
};

// Create a hash_grid
inline hash_grid make_hash_grid(float cell_size);
inline hash_grid make_hash_grid(
const vector<vec3f>& positions, float cell_size);
// Inserts a point into the grid
inline int insert_vertex(hash_grid& grid, vec3f position);
// Finds the nearest neighbors within a given radius
inline void find_neighbors(const hash_grid& grid, vector<int>& neighbors,
vec3f position, float max_radius);
inline void find_neighbors(const hash_grid& grid, vector<int>& neighbors,
int vertex, float max_radius);

} // namespace yocto

// -----------------------------------------------------------------------------
//
//
Expand Down Expand Up @@ -2482,4 +2554,75 @@ inline float turbulence_noise(Noise&& base_noise, vec2f position, int num) {

} // namespace yocto

// -----------------------------------------------------------------------------
// HASH GRID AND NEAREST NEIGHBORS
// -----------------------------------------------------------------------------

namespace yocto {

// Gets the cell index
inline vec3i get_cell_index(const hash_grid& grid, vec3f position) {
auto scaledpos = position * grid.cell_inv_size;
return vec3i{(int)scaledpos.x, (int)scaledpos.y, (int)scaledpos.z};
}

// Create a hash_grid
inline hash_grid make_hash_grid(float cell_size) {
auto grid = hash_grid{};
grid.cell_size = cell_size;
grid.cell_inv_size = 1 / cell_size;
return grid;
}
inline hash_grid make_hash_grid(
const vector<vec3f>& positions, float cell_size) {
auto grid = hash_grid{};
grid.cell_size = cell_size;
grid.cell_inv_size = 1 / cell_size;
for (auto& position : positions) insert_vertex(grid, position);
return grid;
}
// Inserts a point into the grid
inline int insert_vertex(hash_grid& grid, vec3f position) {
auto vertex_id = (int)grid.positions.size();
auto cell = get_cell_index(grid, position);
grid.cells[cell].push_back(vertex_id);
grid.positions.push_back(position);
return vertex_id;
}
// Finds the nearest neighbors within a given radius
inline void find_neighbors(const hash_grid& grid, vector<int>& neighbors,
vec3f position, float max_radius, int skip_id) {
auto cell = get_cell_index(grid, position);
auto cell_radius = (int)(max_radius * grid.cell_inv_size) + 1;
neighbors.clear();
auto max_radius_squared = max_radius * max_radius;
for (auto k = -cell_radius; k <= cell_radius; k++) {
for (auto j = -cell_radius; j <= cell_radius; j++) {
for (auto i = -cell_radius; i <= cell_radius; i++) {
auto ncell = cell + vec3i{i, j, k};
auto cell_iterator = grid.cells.find(ncell);
if (cell_iterator == grid.cells.end()) continue;
auto& ncell_vertices = cell_iterator->second;
for (auto vertex_id : ncell_vertices) {
if (distance_squared(grid.positions[vertex_id], position) >
max_radius_squared)
continue;
if (vertex_id == skip_id) continue;
neighbors.push_back(vertex_id);
}
}
}
}
}
inline void find_neighbors(const hash_grid& grid, vector<int>& neighbors,
vec3f position, float max_radius) {
find_neighbors(grid, neighbors, position, max_radius, -1);
}
inline void find_neighbors(const hash_grid& grid, vector<int>& neighbors,
int vertex, float max_radius) {
find_neighbors(grid, neighbors, grid.positions[vertex], max_radius, vertex);
}

} // namespace yocto

#endif
35 changes: 0 additions & 35 deletions libs/yocto/yocto_sampling.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,31 +177,24 @@ namespace yocto {
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 @@ -458,9 +451,6 @@ inline vector<float> sample_points_cdf(int 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(
Expand All @@ -477,14 +467,6 @@ inline vector<float> sample_lines_cdf(
}
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(
Expand All @@ -501,14 +483,6 @@ inline vector<float> sample_triangles_cdf(
}
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(
Expand All @@ -535,15 +509,6 @@ inline vector<float> sample_quads_cdf(
}
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

Expand Down
7 changes: 3 additions & 4 deletions libs/yocto/yocto_scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -928,10 +928,9 @@ void tesselate_subdiv(
}
}

shape = {};
split_facevarying(shape.quads, shape.positions, shape.normals,
shape.texcoords, subdiv.quadspos, subdiv.quadsnorm, subdiv.quadstexcoord,
subdiv.positions, subdiv.normals, subdiv.texcoords);
shape = fvshape_to_shape(
{subdiv.quadspos, subdiv.quadsnorm, subdiv.quadstexcoord,
subdiv.positions, subdiv.normals, subdiv.texcoords});
}

void tesselate_subdivs(scene_data& scene) {
Expand Down
32 changes: 2 additions & 30 deletions libs/yocto/yocto_sceneio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -919,20 +919,7 @@ void save_fvshape(
const string& filename, const fvshape_data& shape, bool ascii) {
auto ext = path_extension(filename);
if (ext == ".ply" || ext == ".PLY") {
auto ply = ply_model{};
auto split_quads = vector<vec4i>{};
auto split_positions = vector<vec3f>{};
auto split_normals = vector<vec3f>{};
auto split_texcoords = vector<vec2f>{};
split_facevarying(split_quads, split_positions, split_normals,
split_texcoords, shape.quadspos, shape.quadsnorm, shape.quadstexcoord,
shape.positions, shape.normals, shape.texcoords);
// TODO: remove when all as arrays
add_positions(ply, (const vector<array<float, 3>>&)split_positions);
add_normals(ply, (const vector<array<float, 3>>&)split_normals);
add_texcoords(ply, (const vector<array<float, 2>>&)split_texcoords);
add_quads(ply, (const vector<array<int, 4>>&)split_quads);
save_ply(filename, ply);
return save_shape(filename, fvshape_to_shape(shape), ascii);
} else if (ext == ".obj" || ext == ".OBJ") {
auto obj = obj_shape{};
// TODO: remove when all as arrays
Expand All @@ -944,22 +931,7 @@ void save_fvshape(
(const vector<array<int, 4>>&)shape.quadstexcoord, 0);
save_obj(filename, obj);
} else if (ext == ".stl" || ext == ".STL") {
auto stl = stl_model{};
if (!shape.quadspos.empty()) {
auto split_quads = vector<vec4i>{};
auto split_positions = vector<vec3f>{};
auto split_normals = vector<vec3f>{};
auto split_texcoords = vector<vec2f>{};
split_facevarying(split_quads, split_positions, split_normals,
split_texcoords, shape.quadspos, shape.quadsnorm, shape.quadstexcoord,
shape.positions, shape.normals, shape.texcoords);
auto triangles = quads_to_triangles(split_quads);
add_triangles(stl, (const vector<array<int, 3>>&)triangles,
(const vector<array<float, 3>>&)split_positions, {});
} else {
throw io_error{"empty shape " + filename};
}
save_stl(filename, stl);
return save_shape(filename, fvshape_to_shape(shape), ascii);
} else if (ext == ".cpp" || ext == ".CPP") {
auto to_cpp = [](const string& name, const string& vname,
const auto& values) -> string {
Expand Down
Loading

0 comments on commit 8ef2504

Please sign in to comment.