diff options
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/intern/subdiv_ccg.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/source/blender/blenkernel/intern/subdiv_ccg.c b/source/blender/blenkernel/intern/subdiv_ccg.c index 22649a2af07..11d5df4f672 100644 --- a/source/blender/blenkernel/intern/subdiv_ccg.c +++ b/source/blender/blenkernel/intern/subdiv_ccg.c @@ -1618,6 +1618,18 @@ static int prev_adjacent_edge_point_index(const SubdivCCG *subdiv_ccg, const int return point_index - 1; } +/* When the point index corresponds to a grid corner, returs the point index which corresponds to + * the corner of the adjacent grid, as the adjacent edge has two separate points for each grid + * corner at the middle of the edge. */ +static int adjacent_grid_corner_point_index_on_edge(const SubdivCCG *subdiv_ccg, + const int point_index) +{ + if (point_index == subdiv_ccg->grid_size) { + return point_index - 1; + } + return point_index + 1; +} + /* Common implementation of neighbor calculation when input coordinate is at the edge between two * coarse faces, but is not at the coarse vertex. */ static void neighbor_coords_edge_get(const SubdivCCG *subdiv_ccg, @@ -1626,6 +1638,7 @@ static void neighbor_coords_edge_get(const SubdivCCG *subdiv_ccg, SubdivCCGNeighbors *r_neighbors) { + const bool is_corner = is_corner_grid_coord(subdiv_ccg, coord); const int adjacent_edge_index = adjacent_edge_index_from_coord(subdiv_ccg, coord); BLI_assert(adjacent_edge_index >= 0); BLI_assert(adjacent_edge_index < subdiv_ccg->num_adjacent_edges); @@ -1633,15 +1646,27 @@ static void neighbor_coords_edge_get(const SubdivCCG *subdiv_ccg, /* 2 neighbor points along the edge, plus one inner point per every adjacent grid. */ const int num_adjacent_faces = adjacent_edge->num_adjacent_faces; - subdiv_ccg_neighbors_init( - r_neighbors, num_adjacent_faces + 2, (include_duplicates) ? num_adjacent_faces - 1 : 0); + int num_duplicates = 0; + if (include_duplicates) { + num_duplicates += num_adjacent_faces - 1; + if (is_corner) { + /* When the coord is a grid corner, add an extra duplicate per adajacent grid in all adjacent + * faces to the edge. */ + num_duplicates += num_adjacent_faces; + } + } + subdiv_ccg_neighbors_init(r_neighbors, num_adjacent_faces + 2, num_duplicates); const int point_index = adjacent_edge_point_index_from_coord( subdiv_ccg, coord, adjacent_edge_index); + const int point_index_duplicate = adjacent_grid_corner_point_index_on_edge(subdiv_ccg, + point_index); + const int next_point_index = next_adjacent_edge_point_index(subdiv_ccg, point_index); const int prev_point_index = prev_adjacent_edge_point_index(subdiv_ccg, point_index); - for (int i = 0, duplicate_i = num_adjacent_faces; i < num_adjacent_faces; ++i) { + int duplicate_i = num_adjacent_faces; + for (int i = 0; i < num_adjacent_faces; ++i) { SubdivCCGCoord *boundary_coords = adjacent_edge->boundary_coords[i]; /* One step into the grid from the edge for each adjacent face. */ SubdivCCGCoord grid_coord = boundary_coords[point_index]; @@ -1657,7 +1682,15 @@ static void neighbor_coords_edge_get(const SubdivCCG *subdiv_ccg, r_neighbors->coords[duplicate_i + 2] = grid_coord; duplicate_i++; } + + /* When it is a corner, add the duplicate of the adjacent grid in the same face. */ + if (include_duplicates && is_corner) { + SubdivCCGCoord duplicate_corner_grid_coord = boundary_coords[point_index_duplicate]; + r_neighbors->coords[duplicate_i + 2] = duplicate_corner_grid_coord; + duplicate_i++; + } } + BLI_assert(duplicate_i - num_adjacent_faces == num_duplicates); } /* The corner is at the middle of edge between faces. */ |