Code-style: Rename internal parts of pbvh_uv_islands.

- InnerEdge -> FanSegment
- full -> is_manifold
This commit is contained in:
Jeroen Bakker 2023-01-24 15:12:21 +01:00
parent 21eff2c0ac
commit 10a06dfd11
1 changed files with 51 additions and 54 deletions

View File

@ -500,8 +500,7 @@ static std::optional<UVBorderCorner> sharpest_border_corner(UVIsland &island)
}
/** The inner edge of a fan. */
/* TODO: InnerEdge name is incorrect as it links to an edge and primitive. */
struct InnerEdge {
struct FanSegment {
const int primitive_index;
const MLoopTri *primitive;
/* UVs order are already applied. So `uvs[0]` matches `primitive->vertices[vert_order[0]]`. */
@ -512,10 +511,10 @@ struct InnerEdge {
bool found : 1;
} flags;
InnerEdge(const MeshData &mesh_data,
const int primitive_index,
const MLoopTri *primitive,
int vertex)
FanSegment(const MeshData &mesh_data,
const int primitive_index,
const MLoopTri *primitive,
int vertex)
: primitive_index(primitive_index), primitive(primitive)
{
flags.found = false;
@ -559,20 +558,20 @@ struct InnerEdge {
struct Fan {
/* Blades of the fan. */
Vector<InnerEdge> inner_edges;
Vector<FanSegment> segments;
struct {
/**
* Do all segments of the fan make a full fan, or are there parts missing. Non manifold meshes
* can have missing parts.
*/
bool full : 1;
bool is_manifold : 1;
} flags;
Fan(const MeshData &mesh_data, const int vertex)
{
flags.full = true;
flags.is_manifold = true;
int current_edge = mesh_data.vert_to_edge_map[vertex].first();
const int stop_primitive = mesh_data.edge_to_primitive_map[current_edge].first();
int previous_primitive = stop_primitive;
@ -593,7 +592,7 @@ struct Fan {
if (edge_i == current_edge || (edge.vert1 != vertex && edge.vert2 != vertex)) {
continue;
}
inner_edges.append(InnerEdge(mesh_data, other_primitive_i, &other_looptri, vertex));
segments.append(FanSegment(mesh_data, other_primitive_i, &other_looptri, vertex));
current_edge = edge_i;
previous_primitive = other_primitive_i;
stop = true;
@ -601,7 +600,7 @@ struct Fan {
}
}
if (stop == false) {
flags.full = false;
flags.is_manifold = false;
break;
}
if (stop_primitive == previous_primitive) {
@ -613,7 +612,7 @@ struct Fan {
int count_edges_not_added() const
{
int result = 0;
for (const InnerEdge &fan_edge : inner_edges) {
for (const FanSegment &fan_edge : segments) {
if (!fan_edge.flags.found) {
result++;
}
@ -626,14 +625,14 @@ struct Fan {
Vector<int> mesh_primitive_indices = connecting_mesh_primitive_indices(uv_vertex);
/* Go over all fan edges to find if they can be found as primitive around the uv vertex. */
for (InnerEdge &fan_edge : inner_edges) {
for (FanSegment &fan_edge : segments) {
fan_edge.flags.found = mesh_primitive_indices.contains(fan_edge.primitive_index);
}
}
void init_uv_coordinates(const MeshData &mesh_data, UVVertex &uv_vertex)
{
for (InnerEdge &fan_edge : inner_edges) {
for (FanSegment &fan_edge : segments) {
int other_v = mesh_data.loops[fan_edge.primitive->tri[fan_edge.vert_order[0]]].v;
if (other_v == uv_vertex.vertex) {
other_v = mesh_data.loops[fan_edge.primitive->tri[fan_edge.vert_order[1]]].v;
@ -650,9 +649,9 @@ struct Fan {
}
}
inner_edges.last().uvs[2] = inner_edges.first().uvs[1];
for (int i = 0; i < inner_edges.size() - 1; i++) {
inner_edges[i].uvs[2] = inner_edges[i + 1].uvs[1];
segments.last().uvs[2] = segments.first().uvs[1];
for (int i = 0; i < segments.size() - 1; i++) {
segments[i].uvs[2] = segments[i + 1].uvs[1];
}
}
@ -663,8 +662,8 @@ struct Fan {
*/
bool contains_vertex_on_outside(const MeshData &mesh_data, const int vertex_index) const
{
for (const InnerEdge &inner_edge : inner_edges) {
int v2 = mesh_data.loops[inner_edge.primitive->tri[inner_edge.vert_order[1]]].v;
for (const FanSegment &segment : segments) {
int v2 = mesh_data.loops[segment.primitive->tri[segment.vert_order[1]]].v;
if (vertex_index == v2) {
return true;
}
@ -674,15 +673,15 @@ struct Fan {
#endif
static bool is_path_valid(const Span<InnerEdge *> &path,
static bool is_path_valid(const Span<FanSegment *> &path,
const MeshData &mesh_data,
const int from_vertex,
const int to_vertex)
{
int current_vert = from_vertex;
for (InnerEdge *inner_edge : path) {
int v1 = mesh_data.loops[inner_edge->primitive->tri[inner_edge->vert_order[1]]].v;
int v2 = mesh_data.loops[inner_edge->primitive->tri[inner_edge->vert_order[2]]].v;
for (FanSegment *segment : path) {
int v1 = mesh_data.loops[segment->primitive->tri[segment->vert_order[1]]].v;
int v2 = mesh_data.loops[segment->primitive->tri[segment->vert_order[2]]].v;
if (!ELEM(current_vert, v1, v2)) {
return false;
}
@ -697,23 +696,22 @@ struct Fan {
*
* Algorithm only uses the winding order of the given fan segments.
*/
static Vector<InnerEdge *> path_between(const Span<InnerEdge *> edge_order,
const MeshData &mesh_data,
const int from_vertex,
const int to_vertex,
const bool reversed)
static Vector<FanSegment *> path_between(const Span<FanSegment *> edge_order,
const MeshData &mesh_data,
const int from_vertex,
const int to_vertex,
const bool reversed)
{
const int from_vert_order = 1;
const int to_vert_order = 2;
const int index_increment = reversed ? -1 : 1;
Vector<InnerEdge *> result;
Vector<FanSegment *> result;
result.reserve(edge_order.size());
int index = 0;
while (true) {
InnerEdge *inner_edge = edge_order[index];
int v2 =
mesh_data.loops[inner_edge->primitive->tri[inner_edge->vert_order[from_vert_order]]].v;
FanSegment *segment = edge_order[index];
int v2 = mesh_data.loops[segment->primitive->tri[segment->vert_order[from_vert_order]]].v;
if (v2 == from_vertex) {
break;
}
@ -721,11 +719,10 @@ struct Fan {
}
while (true) {
InnerEdge *inner_edge = edge_order[index];
result.append(inner_edge);
FanSegment *segment = edge_order[index];
result.append(segment);
int v3 =
mesh_data.loops[inner_edge->primitive->tri[inner_edge->vert_order[to_vert_order]]].v;
int v3 = mesh_data.loops[segment->primitive->tri[segment->vert_order[to_vert_order]]].v;
if (v3 == to_vertex) {
break;
}
@ -742,36 +739,36 @@ struct Fan {
* Score is determined by counting the number of steps and subtracting that with steps that have
* not yet been visited.
*/
static int64_t score(const Span<InnerEdge *> solution)
static int64_t score(const Span<FanSegment *> solution)
{
int64_t not_visited_steps = 0;
for (InnerEdge *inner_edge : solution) {
if (!inner_edge->flags.found) {
for (FanSegment *segment : solution) {
if (!segment->flags.found) {
not_visited_steps++;
}
}
return solution.size() - not_visited_steps;
}
Vector<InnerEdge *> best_path_between(const MeshData &mesh_data,
const int from_vertex,
const int to_vertex)
Vector<FanSegment *> best_path_between(const MeshData &mesh_data,
const int from_vertex,
const int to_vertex)
{
BLI_assert_msg(contains_vertex_on_outside(mesh_data, from_vertex),
"Inconsistency detected, `from_vertex` isn't part of the outside of the fan.");
BLI_assert_msg(contains_vertex_on_outside(mesh_data, to_vertex),
"Inconsistency detected, `to_vertex` isn't part of the outside of the fan.");
if (to_vertex == from_vertex) {
return Vector<InnerEdge *>();
return Vector<FanSegment *>();
}
Array<InnerEdge *> edges(inner_edges.size());
for (int64_t index : inner_edges.index_range()) {
edges[index] = &inner_edges[index];
Array<FanSegment *> edges(segments.size());
for (int64_t index : segments.index_range()) {
edges[index] = &segments[index];
}
Vector<InnerEdge *> winding_1 = path_between(edges, mesh_data, from_vertex, to_vertex, false);
Vector<InnerEdge *> winding_2 = path_between(edges, mesh_data, from_vertex, to_vertex, true);
Vector<FanSegment *> winding_1 = path_between(edges, mesh_data, from_vertex, to_vertex, false);
Vector<FanSegment *> winding_2 = path_between(edges, mesh_data, from_vertex, to_vertex, true);
bool winding_1_valid = is_path_valid(winding_1, mesh_data, from_vertex, to_vertex);
bool winding_2_valid = is_path_valid(winding_2, mesh_data, from_vertex, to_vertex);
@ -784,7 +781,7 @@ struct Fan {
}
if (!winding_1_valid && !winding_2_valid) {
BLI_assert_msg(false, "Both solutions aren't valid.");
return Vector<InnerEdge *>();
return Vector<FanSegment *>();
}
if (score(winding_1) < score(winding_2)) {
return winding_1;
@ -794,8 +791,8 @@ struct Fan {
void print_debug(const MeshData &mesh_data) const
{
for (const InnerEdge &inner_edge : inner_edges) {
inner_edge.print_debug(mesh_data);
for (const FanSegment &segment : segments) {
segment.print_debug(mesh_data);
}
std::cout << "\n";
}
@ -907,7 +904,7 @@ static void extend_at_vert(const MeshData &mesh_data,
UVVertex *uv_vertex = corner.second->get_uv_vertex(0);
Fan fan(mesh_data, uv_vertex->vertex);
if (!fan.flags.full) {
if (!fan.flags.is_manifold) {
return;
}
fan.init_uv_coordinates(mesh_data, *uv_vertex);
@ -917,7 +914,7 @@ static void extend_at_vert(const MeshData &mesh_data,
/* In 3d space everything can connected, but in uv space it may not.
* in this case in the space between we should extract the primitives to be added
* from the fan. */
Vector<InnerEdge *> winding_solution = fan.best_path_between(
Vector<FanSegment *> winding_solution = fan.best_path_between(
mesh_data, corner.first->get_uv_vertex(0)->vertex, corner.second->get_uv_vertex(1)->vertex);
/*
@ -987,7 +984,7 @@ static void extend_at_vert(const MeshData &mesh_data,
float factor = (segment_index + 1.0f) / num_to_add;
float2 new_uv = corner.uv(factor, min_uv_distance);
InnerEdge &segment = *winding_solution[segment_index];
FanSegment &segment = *winding_solution[segment_index];
const int fill_primitive_i = segment.primitive_index;
const MLoopTri &fill_primitive = mesh_data.looptris[fill_primitive_i];