Skip to content

Commit

Permalink
Moved more code from shape
Browse files Browse the repository at this point in the history
  • Loading branch information
xelatihy committed Jan 29, 2024
1 parent 8c7ecb3 commit 4e871d0
Show file tree
Hide file tree
Showing 5 changed files with 247 additions and 372 deletions.
4 changes: 2 additions & 2 deletions apps/yconverts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ void run(const vector<string>& args) {
}

// convert to edges
auto edges = !shape.triangles.empty() ? get_edges(shape.triangles)
: get_edges(shape.quads);
auto edges = !shape.triangles.empty() ? triangles_edges(shape.triangles)
: quads_edges(shape.quads);
shape = lines_to_cylinders(edges, shape.positions, 4, 0.001f);
}

Expand Down
34 changes: 17 additions & 17 deletions libs/yocto/yocto_diagram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -525,10 +525,10 @@ void add_shape(diagram_scene& diagram, const diagram_frame& frame,
// TODO: wireframe
auto wireframe = true;
if (wireframe && shape.lines.empty() && !shape.triangles.empty()) {
shape.lines = get_edges(shape.triangles);
shape.lines = triangles_edges(shape.triangles);
}
if (wireframe && shape.lines.empty() && !shape.quads.empty()) {
shape.lines = get_edges(shape.quads);
shape.lines = quads_edges(shape.quads);
}

auto labels = diagram_labels{};
Expand Down Expand Up @@ -725,7 +725,7 @@ diagram_shape dquads(const vector<vec4i>& quads, const vector<vec3f>& positions,
} else {
shape.quads = quads;
}
shape.lines = get_edges(shape.quads);
shape.lines = quads_edges(shape.quads);

return shape;
}
Expand All @@ -750,7 +750,7 @@ diagram_shape dtriangles(const vector<vec3i>& triangles,
} else {
shape.triangles = triangles;
}
shape.lines = get_edges(shape.triangles);
shape.lines = triangles_edges(shape.triangles);

return shape;
}
Expand All @@ -768,10 +768,10 @@ diagram_shape dshape(const shape_data& shape_, bool wireframe) {
shape.quads = shape_.quads;

if (wireframe && shape.lines.empty() && !shape.triangles.empty()) {
shape.lines = get_edges(shape.triangles);
shape.lines = triangles_edges(shape.triangles);
}
if (wireframe && shape.lines.empty() && !shape.quads.empty()) {
shape.lines = get_edges(shape.quads);
shape.lines = quads_edges(shape.quads);
}

return shape;
Expand Down Expand Up @@ -822,7 +822,7 @@ diagram_shape drect(vec2f aspect) {
shape.texcoords = dconstants::quad_texcoords;

shape.quads = dconstants::quad_quads;
shape.lines = get_edges(shape.quads);
shape.lines = quads_edges(shape.quads);

return shape;
}
Expand Down Expand Up @@ -940,7 +940,7 @@ diagram_shape dcube() {

shape.quads = dconstants::cube_quads;

shape.lines = get_edges(shape.quads);
shape.lines = quads_edges(shape.quads);

return shape;
}
Expand All @@ -951,7 +951,7 @@ diagram_shape dcube(int steps) {
shape.normals = shape_.normals;
shape.texcoords = shape_.texcoords;
shape.quads = shape_.quads;
shape.lines = get_edges(shape.quads);
shape.lines = quads_edges(shape.quads);
return shape;
}

Expand Down Expand Up @@ -979,7 +979,7 @@ diagram_shape dsphere(int steps, bool isolines) {
}
}
} else {
shape.lines = get_edges(shape.quads);
shape.lines = quads_edges(shape.quads);
}

return shape;
Expand Down Expand Up @@ -1007,7 +1007,7 @@ diagram_shape duvsphere(int steps, bool isolines) {
}
}
} else {
shape.lines = get_edges(shape.quads);
shape.lines = quads_edges(shape.quads);
}

return shape;
Expand Down Expand Up @@ -1041,7 +1041,7 @@ diagram_shape dhemisphere(int steps, bool isolines) {
}
}
} else {
shape.lines = get_edges(shape.quads);
shape.lines = quads_edges(shape.quads);
}

return shape;
Expand All @@ -1066,7 +1066,7 @@ diagram_shape dcone(int steps, bool isolines) {
shape.lines.push_back({offset + idx, offset + (idx + 1) % steps});
}
} else {
shape.lines = get_edges(shape.quads);
shape.lines = quads_edges(shape.quads);
}
return shape;
}
Expand Down Expand Up @@ -1117,7 +1117,7 @@ diagram_shape dbbox(const bbox3f& bbox_, float epsilon) {
shape.positions = positions_;

shape.quads = dconstants::cube_quads;
shape.lines = get_edges(shape.quads);
shape.lines = quads_edges(shape.quads);

return shape;
}
Expand Down Expand Up @@ -1150,7 +1150,7 @@ diagram_shape dgrid(vec2i steps) {
shape.positions = shape_.positions;

shape.quads = shape_.quads;
shape.lines = get_edges(shape.quads);
shape.lines = quads_edges(shape.quads);

return shape;
}
Expand Down Expand Up @@ -1212,7 +1212,7 @@ diagram_shape daffinegrid(vec3f axes_a, vec3f axes_b, vec2i steps) {
shape.positions = positions_;

shape.quads = shape_.quads;
shape.lines = get_edges(shape.quads);
shape.lines = quads_edges(shape.quads);

return shape;
}
Expand All @@ -1228,7 +1228,7 @@ diagram_shape dimagerect(vec2i size) {
shape.texcoords = dconstants::quad_texcoords;

shape.quads = dconstants::quad_quads;
shape.lines = get_edges(shape.quads);
shape.lines = quads_edges(shape.quads);

return shape;
}
Expand Down
188 changes: 186 additions & 2 deletions libs/yocto/yocto_modeling.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ static pair<vector<vec4i>, vector<T>> subdivide_beziers(
} // namespace yocto

// -----------------------------------------------------------------------------
// MESH EDGE HELPERS
// MESH EDGES AND ADJACENCIES
// -----------------------------------------------------------------------------
namespace yocto {

Expand All @@ -281,6 +281,23 @@ inline pair<vector<vec2i>, vector<vec2i>> quads_edges_boundaries(
inline pair<vector<vec2i>, vector<vec2i>> faces_edges_boundaries(
const vector<vec3i>& triangles, const vector<vec4i>& quads);

// Build adjacencies between faces (sorted counter-clockwise)
inline vector<vec3i> face_adjacencies(const vector<vec3i>& triangles);

// Build adjacencies between vertices (sorted counter-clockwise)
inline vector<vector<int>> vertex_adjacencies(
const vector<vec3i>& triangles, const vector<vec3i>& adjacencies);

// Compute boundaries as a list of loops (sorted counter-clockwise)
inline vector<vector<int>> ordered_boundaries(const vector<vec3i>& triangles,
const vector<vec3i>& adjacency, int num_vertices);

// Build adjacencies between each vertex and its adjacent faces.
// Adjacencies are sorted counter-clockwise and have same starting points as
// vertex_adjacencies()
inline vector<vector<int>> vertex_to_faces_adjacencies(
const vector<vec3i>& triangles, const vector<vec3i>& adjacencies);

} // namespace yocto

// -----------------------------------------------------------------------------
Expand Down Expand Up @@ -1275,7 +1292,7 @@ static pair<vector<vec4i>, vector<T>> subdivide_beziers(
} // namespace yocto

// -----------------------------------------------------------------------------
// MESH EDGE HELPERS
// EDGE AND ADJACENCIES FUNCTIONS
// -----------------------------------------------------------------------------
namespace yocto {

Expand Down Expand Up @@ -1428,6 +1445,173 @@ inline pair<vector<vec2i>, vector<vec2i>> faces_edges_boundaries(
return {edges, boundaries};
}

// Build adjacencies between faces (sorted counter-clockwise)
inline vector<vec3i> face_adjacencies(const vector<vec3i>& triangles) {
struct face_edge {
vec2i edge;
int face;
int edge_index;
};
auto get_edge = [](vec3i triangle, int i) -> vec2i {
auto x = triangle[i], y = triangle[i < 2 ? i + 1 : 0];
return x < y ? vec2i{x, y} : vec2i{y, x};
};
auto edges = vector<face_edge>{};
edges.reserve(triangles.size() * 3);
for (auto tid : range((int)triangles.size())) {
for (auto k = 0; k < 3; ++k) {
auto edge = get_edge(triangles[tid], k);
edges.push_back({edge, tid, k});
}
}
sort(edges.begin(), edges.end(), [](auto a_, auto b_) {
auto a = a_.edge, b = b_.edge;
return a.x < b.x || (a.x == b.x && a.y < b.y);
});

auto adjacencies = vector<vec3i>{triangles.size(), vec3i{-1, -1, -1}};
for (auto eid : range((int)edges.size() - 1)) {
if (edges[eid].edge == edges[eid + 1].edge) continue;
adjacencies[edges[eid].face][edges[eid].edge_index] = edges[eid + 1].face;
adjacencies[edges[eid + 1].face][edges[eid + 1].edge_index] =
edges[eid].face;
}

return adjacencies;
}

// Build adjacencies between vertices (sorted counter-clockwise)
inline vector<vector<int>> vertex_adjacencies(
const vector<vec3i>& triangles, const vector<vec3i>& adjacencies) {
auto find_index = [](vec3i v, int x) {
if (v.x == x) return 0;
if (v.y == x) return 1;
if (v.z == x) return 2;
return -1;
};

// For each vertex, find any adjacent face.
auto num_vertices = 0;
auto face_from_vertex = vector<int>(triangles.size() * 3, -1);

for (auto i = 0; i < (int)triangles.size(); ++i) {
for (auto k : range(3)) {
face_from_vertex[triangles[i][k]] = i;
num_vertices = max(num_vertices, triangles[i][k]);
}
}

// Init result.
auto result = vector<vector<int>>(num_vertices);

// For each vertex, loop around it and build its adjacency.
for (auto i = 0; i < num_vertices; ++i) {
result[i].reserve(6);
auto first_face = face_from_vertex[i];
if (first_face == -1) continue;

auto face = first_face;
while (true) {
auto k = find_index(triangles[face], i);
k = k != 0 ? k - 1 : 2;
result[i].push_back(triangles[face][k]);
face = adjacencies[face][k];
if (face == -1) break;
if (face == first_face) break;
}
}

return result;
}

// Build adjacencies between each vertex and its adjacent faces.
// Adjacencies are sorted counter-clockwise and have same starting points as
// vertex_adjacencies()
inline vector<vector<int>> vertex_to_faces_adjacencies(
const vector<vec3i>& triangles, const vector<vec3i>& adjacencies) {
auto find_index = [](vec3i v, int x) {
if (v.x == x) return 0;
if (v.y == x) return 1;
if (v.z == x) return 2;
return -1;
};

// For each vertex, find any adjacent face.
auto num_vertices = 0;
auto face_from_vertex = vector<int>(triangles.size() * 3, -1);

for (auto i = 0; i < (int)triangles.size(); ++i) {
for (auto k : range(3)) {
face_from_vertex[triangles[i][k]] = i;
num_vertices = max(num_vertices, triangles[i][k]);
}
}

// Init result.
auto result = vector<vector<int>>(num_vertices);

// For each vertex, loop around it and build its adjacency.
for (auto i = 0; i < num_vertices; ++i) {
result[i].reserve(6);
auto first_face = face_from_vertex[i];
if (first_face == -1) continue;

auto face = first_face;
while (true) {
auto k = find_index(triangles[face], i);
k = k != 0 ? k - 1 : 2;
face = adjacencies[face][k];
result[i].push_back(face);
if (face == -1) break;
if (face == first_face) break;
}
}

return result;
}

// Compute boundaries as a list of loops (sorted counter-clockwise)
inline vector<vector<int>> ordered_boundaries(const vector<vec3i>& triangles,
const vector<vec3i>& adjacency, int num_vertices) {
// map every boundary vertex to its next one
auto next_vert = vector<int>(num_vertices, -1);
for (auto i = 0; i < (int)triangles.size(); ++i) {
for (auto k = 0; k < 3; ++k) {
if (adjacency[i][k] == -1)
next_vert[triangles[i][k]] = triangles[i][(k + 1) % 3];
}
}

// result
auto boundaries = vector<vector<int>>();

// arrange boundary vertices in loops
for (auto i : range(next_vert.size())) {
if (next_vert[i] == -1) continue;

// add new empty boundary
boundaries.emplace_back();
auto current = (int)i;

while (true) {
auto next = next_vert[current];
if (next == -1) {
return {};
}
next_vert[current] = -1;
boundaries.back().push_back(current);

// close loop if necessary
if (next == i)
break;
else
current = next;
}
}

return boundaries;
}

} // namespace yocto

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

0 comments on commit 4e871d0

Please sign in to comment.