Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Carlisle <carlisle.b3d@gmail.com>2022-01-31 20:32:31 +0300
committerAaron Carlisle <carlisle.b3d@gmail.com>2022-01-31 20:32:31 +0300
commit2bd30272ea27c6b71b50f6d6bf95c69a4006579a (patch)
tree2540f358648fb2a795cf830ed2e98aeb023d4a98
parent64ca0f44cbf03ecb63be7150076e25bd6deb64e0 (diff)
parent5edb924e57348ce69de8a977258589b9a7a8de02 (diff)
Merge branch 'blender-v3.1-release'
-rw-r--r--source/blender/editors/object/object_bake_api.c24
-rw-r--r--source/blender/editors/space_node/node_draw.cc2
-rw-r--r--source/blender/render/intern/texture_margin.cc100
3 files changed, 90 insertions, 36 deletions
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index d56d0edd5a2..f52d2103fff 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -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(
diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc
index 82da890fa9b..834bb3e5802 100644
--- a/source/blender/editors/space_node/node_draw.cc
+++ b/source/blender/editors/space_node/node_draw.cc
@@ -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;
diff --git a/source/blender/render/intern/texture_margin.cc b/source/blender/render/intern/texture_margin.cc
index 4fbd20eeaf1..bb4b82645f0 100644
--- a/source/blender/render/intern/texture_margin.cc
+++ b/source/blender/render/intern/texture_margin.cc
@@ -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);