Merge branch 'blender-v3.1-release'

This commit is contained in:
Aaron Carlisle 2022-01-31 12:32:31 -05:00
commit 2bd30272ea
3 changed files with 90 additions and 36 deletions

View File

@ -188,7 +188,7 @@ static bool write_internal_bake_pixels(Image *image,
const char margin_type,
const bool is_clear,
const bool is_noncolor,
Mesh const *mesh,
Mesh const *mesh_eval,
char const *uv_layer)
{
ImBuf *ibuf;
@ -285,7 +285,7 @@ static bool write_internal_bake_pixels(Image *image,
/* margins */
if (margin > 0) {
RE_bake_margin(ibuf, mask_buffer, margin, margin_type, mesh, uv_layer);
RE_bake_margin(ibuf, mask_buffer, margin, margin_type, mesh_eval, uv_layer);
}
ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
@ -334,7 +334,7 @@ static bool write_external_bake_pixels(const char *filepath,
const int margin_type,
ImageFormatData *im_format,
const bool is_noncolor,
Mesh const *mesh,
Mesh const *mesh_eval,
char const *uv_layer)
{
ImBuf *ibuf = NULL;
@ -392,7 +392,7 @@ static bool write_external_bake_pixels(const char *filepath,
mask_buffer = MEM_callocN(sizeof(char) * num_pixels, "Bake Mask");
RE_bake_mask_fill(pixel_array, num_pixels, mask_buffer);
RE_bake_margin(ibuf, mask_buffer, margin, margin_type, mesh, uv_layer);
RE_bake_margin(ibuf, mask_buffer, margin, margin_type, mesh_eval, uv_layer);
if (mask_buffer) {
MEM_freeN(mask_buffer);
@ -774,10 +774,10 @@ static bool bake_targets_output_internal(const BakeAPIRender *bkr,
BakeTargets *targets,
Object *ob,
BakePixel *pixel_array,
ReportList *reports)
ReportList *reports,
Mesh *mesh_eval)
{
bool all_ok = true;
const Mesh *me = (Mesh *)ob->data;
for (int i = 0; i < targets->num_images; i++) {
BakeImage *bk_image = &targets->images[i];
@ -791,7 +791,7 @@ static bool bake_targets_output_internal(const BakeAPIRender *bkr,
bkr->margin_type,
bkr->is_clear,
targets->is_noncolor,
me,
mesh_eval,
bkr->uv_layer);
/* might be read by UI to set active image for display */
@ -852,7 +852,7 @@ static bool bake_targets_output_external(const BakeAPIRender *bkr,
BakeTargets *targets,
Object *ob,
Object *ob_eval,
Mesh *me,
Mesh *mesh_eval,
BakePixel *pixel_array,
ReportList *reports)
{
@ -886,8 +886,8 @@ static bool bake_targets_output_external(const BakeAPIRender *bkr,
if (ob_eval->mat[i]) {
BLI_path_suffix(name, FILE_MAX, ob_eval->mat[i]->id.name + 2, "_");
}
else if (me->mat[i]) {
BLI_path_suffix(name, FILE_MAX, me->mat[i]->id.name + 2, "_");
else if (mesh_eval->mat[i]) {
BLI_path_suffix(name, FILE_MAX, mesh_eval->mat[i]->id.name + 2, "_");
}
else {
/* if everything else fails, use the material index */
@ -909,7 +909,7 @@ static bool bake_targets_output_external(const BakeAPIRender *bkr,
bkr->margin_type,
&bake->im_format,
targets->is_noncolor,
me,
mesh_eval,
bkr->uv_layer);
if (!ok) {
@ -1211,7 +1211,7 @@ static bool bake_targets_output(const BakeAPIRender *bkr,
{
if (bkr->target == R_BAKE_TARGET_IMAGE_TEXTURES) {
if (bkr->save_mode == R_BAKE_SAVE_INTERNAL) {
return bake_targets_output_internal(bkr, targets, ob, pixel_array, reports);
return bake_targets_output_internal(bkr, targets, ob, pixel_array, reports, me_eval);
}
if (bkr->save_mode == R_BAKE_SAVE_EXTERNAL) {
return bake_targets_output_external(

View File

@ -2028,7 +2028,7 @@ static void node_draw_basis(const bContext &C,
}
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_4fv(&rect, false, BASIS_RAD, color_outline);
UI_draw_roundbox_4fv(&rect, false, BASIS_RAD + outline_width, color_outline);
}
float scale;

View File

@ -52,7 +52,8 @@ namespace blender::render::texturemargin {
* adjacency tables.
*/
class TextureMarginMap {
static const int directions[4][2];
static const int directions[8][2];
static const int distances[8];
/* Maps UV-edges to their corresponding UV-edge. */
Vector<int> loop_adjacency_map_;
@ -142,13 +143,13 @@ class TextureMarginMap {
}
/* The map contains 2 kinds of pixels: DijkstraPixels and polygon indices. The top bit determines
* what kind it is. With the top bit set, it is a 'dijkstra' pixel. The bottom 3 bits encode the
* direction of the shortest path and the remaining 28 bits are used to store the distance. If
* what kind it is. With the top bit set, it is a 'dijkstra' pixel. The bottom 4 bits encode the
* direction of the shortest path and the remaining 27 bits are used to store the distance. If
* the top bit is not set, the rest of the bits is used to store the polygon index.
*/
#define PackDijkstraPixel(dist, dir) (0x80000000 + ((dist) << 3) + (dir))
#define DijkstraPixelGetDistance(dp) (((dp) ^ 0x80000000) >> 3)
#define DijkstraPixelGetDirection(dp) ((dp)&0x7)
#define PackDijkstraPixel(dist, dir) (0x80000000 + ((dist) << 4) + (dir))
#define DijkstraPixelGetDistance(dp) (((dp) ^ 0x80000000) >> 4)
#define DijkstraPixelGetDirection(dp) ((dp)&0xF)
#define IsDijkstraPixel(dp) ((dp)&0x80000000)
#define DijkstraPixelIsUnset(dp) ((dp) == 0xFFFFFFFF)
@ -173,13 +174,13 @@ class TextureMarginMap {
for (int y = 0; y < h_; y++) {
for (int x = 0; x < w_; x++) {
if (DijkstraPixelIsUnset(get_pixel(x, y))) {
for (int i = 0; i < 4; i++) {
for (int i = 0; i < 8; i++) {
int xx = x - directions[i][0];
int yy = y - directions[i][1];
if (xx >= 0 && xx < w_ && yy >= 0 && yy < w_ && !IsDijkstraPixel(get_pixel(xx, yy))) {
set_pixel(x, y, PackDijkstraPixel(1, i));
active_pixels.append(DijkstraActivePixel(1, x, y));
set_pixel(x, y, PackDijkstraPixel(distances[i], i));
active_pixels.append(DijkstraActivePixel(distances[i], x, y));
break;
}
}
@ -196,17 +197,16 @@ class TextureMarginMap {
int dist = p.distance;
dist++;
if (dist < margin) {
for (int i = 0; i < 4; i++) {
if (dist < 2 * (margin + 1)) {
for (int i = 0; i < 8; i++) {
int x = p.x + directions[i][0];
int y = p.y + directions[i][1];
if (x >= 0 && x < w_ && y >= 0 && y < h_) {
uint32_t dp = get_pixel(x, y);
if (IsDijkstraPixel(dp) && (DijkstraPixelGetDistance(dp) > dist)) {
BLI_assert(abs((int)DijkstraPixelGetDirection(dp) - (int)i) != 2);
set_pixel(x, y, PackDijkstraPixel(dist, i));
active_pixels.append(DijkstraActivePixel(dist, x, y));
if (IsDijkstraPixel(dp) && (DijkstraPixelGetDistance(dp) > dist + distances[i])) {
BLI_assert(DijkstraPixelGetDirection(dp) != i);
set_pixel(x, y, PackDijkstraPixel(dist + distances[i], i));
active_pixels.append(DijkstraActivePixel(dist + distances[i], x, y));
std::push_heap(active_pixels.begin(), active_pixels.end(), cmp_dijkstrapixel_fun);
}
}
@ -236,7 +236,7 @@ class TextureMarginMap {
xx -= directions[direction][0];
yy -= directions[direction][1];
dp = get_pixel(xx, yy);
dist--;
dist -= distances[direction];
BLI_assert(!dist || (dist == DijkstraPixelGetDistance(dp)));
direction = DijkstraPixelGetDirection(dp);
}
@ -249,7 +249,7 @@ class TextureMarginMap {
int other_poly;
bool found_pixel_in_polygon = false;
if (lookup_pixel(x, y, poly, &destX, &destY, &other_poly)) {
if (lookup_pixel_polygon_neighbourhood(x, y, &poly, &destX, &destY, &other_poly)) {
for (int i = 0; i < maxPolygonSteps; i++) {
/* Force to pixel grid. */
@ -261,8 +261,12 @@ class TextureMarginMap {
break;
}
float dist_to_edge;
/* Look up again, but starting from the polygon we were expected to land in. */
lookup_pixel(nx, ny, other_poly, &destX, &destY, &other_poly);
if (!lookup_pixel(nx, ny, other_poly, &destX, &destY, &other_poly, &dist_to_edge)) {
found_pixel_in_polygon = false;
break;
}
}
if (found_pixel_in_polygon) {
@ -320,12 +324,59 @@ class TextureMarginMap {
}
}
/* Call lookup_pixel for the start_poly. If that fails, try the adjacent polygons as well.
* Because the Dijkstra is not vey exact in determining which polygon is the closest, the
* polygon we need can be the one next to the one the Dijkstra map provides. To prevent missing
* pixels also check the neighbouring polygons. */
bool lookup_pixel_polygon_neighbourhood(
float x, float y, uint32_t *r_start_poly, float *r_destx, float *r_desty, int *r_other_poly)
{
float found_dist;
if (lookup_pixel(x, y, *r_start_poly, r_destx, r_desty, r_other_poly, &found_dist)) {
return true;
}
int loopstart = mpoly_[*r_start_poly].loopstart;
int totloop = mpoly_[*r_start_poly].totloop;
float destx, desty;
int foundpoly;
float mindist = -1.f;
/* Loop over all adjacent polyons and determine which edge is closest.
* This could be optimized by only inspecting neigbours which are on the edge of an island.
* But it seems fast enough for now and that would add a lot of complexity. */
for (int i = 0; i < totloop; i++) {
int otherloop = loop_adjacency_map_[i + loopstart];
uint32_t poly = loop_to_poly_map_[otherloop];
if (lookup_pixel(x, y, poly, &destx, &desty, &foundpoly, &found_dist)) {
if (mindist < 0.f || found_dist < mindist) {
mindist = found_dist;
*r_other_poly = foundpoly;
;
*r_destx = destx;
*r_desty = desty;
*r_start_poly = poly;
}
}
}
return mindist >= 0.f;
}
/* Find which edge of the src_poly is closest to x,y. Look up it's adjacent UV-edge and polygon.
* Then return the location of the equivalent pixel in the other polygon.
* Returns true if a new pixel location was found, false if it wasn't, which can happen if the
* margin pixel is on a corner, or the UV-edge doesn't have an adjacent polygon. */
bool lookup_pixel(
float x, float y, int src_poly, float *r_destx, float *r_desty, int *r_other_poly)
bool lookup_pixel(float x,
float y,
int src_poly,
float *r_destx,
float *r_desty,
int *r_other_poly,
float *r_dist_to_edge)
{
float2 point(x, y);
@ -385,6 +436,8 @@ class TextureMarginMap {
return false;
}
*r_dist_to_edge = found_dist;
/* Get the 'other' edge. I.E. the UV edge from the neighbor polygon. */
int other_edge = loop_adjacency_map_[found_edge];
@ -425,7 +478,9 @@ class TextureMarginMap {
}
}; // class TextureMarginMap
const int TextureMarginMap::directions[4][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
const int TextureMarginMap::directions[8][2] = {
{-1, 0}, {-1, -1}, {0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1}, {-1, 1}};
const int TextureMarginMap::distances[8] = {2, 3, 2, 3, 2, 3, 2, 3};
static void generate_margin(ImBuf *ibuf,
char *mask,
@ -470,7 +525,6 @@ static void generate_margin(ImBuf *ibuf,
else {
BLI_assert(dm != nullptr);
BLI_assert(me == nullptr);
BLI_assert(mloopuv == nullptr);
totpoly = dm->getNumPolys(dm);
totedge = dm->getNumEdges(dm);
totloop = dm->getNumLoops(dm);