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:
authorJeroen Bakker <jeroen@blender.org>2022-05-20 16:38:49 +0300
committerJeroen Bakker <jeroen@blender.org>2022-05-20 16:38:49 +0300
commitec7cbd4c9a35ea5471502ac38897165f2699bb75 (patch)
tree7b9bd212a2d248df47c8c6b0058217ba9e01a820
parent4708ee96e76e4c48d3a2afa48e655b5f679d9015 (diff)
Create mask and dilate.
-rw-r--r--source/blender/blenkernel/BKE_uv_islands.hh166
-rw-r--r--source/blender/blenkernel/intern/pbvh_pixels.cc4
2 files changed, 162 insertions, 8 deletions
diff --git a/source/blender/blenkernel/BKE_uv_islands.hh b/source/blender/blenkernel/BKE_uv_islands.hh
index ac448ddb0ad..32e4bc200a0 100644
--- a/source/blender/blenkernel/BKE_uv_islands.hh
+++ b/source/blender/blenkernel/BKE_uv_islands.hh
@@ -82,9 +82,16 @@ struct UVIsland {
UVIsland(const UVPrimitive &primitive)
{
+ append(primitive);
+ }
+
+ private:
+ void append(const UVPrimitive &primitive)
+ {
primitives.append(primitive);
}
+ public:
bool has_shared_edge(const UVPrimitive &primitive) const
{
for (const UVPrimitive &prim : primitives) {
@@ -116,7 +123,7 @@ struct UVIsland {
"Cannot extend as primitive has to many shared edges with UV island. "
"Inconsistent UVIsland?");
- primitives.append(new_prim);
+ append(new_prim);
}
/**
@@ -128,22 +135,22 @@ struct UVIsland {
* */
void join(const UVIsland &other, const UVPrimitive &primitive)
{
- Vector<const UVPrimitive *> extend;
- Vector<const UVPrimitive *> append;
+ Vector<const UVPrimitive *> prims_to_extend;
+ Vector<const UVPrimitive *> prims_to_append;
for (const UVPrimitive &other_prim : other.primitives) {
if (primitive.has_shared_edge(other_prim)) {
- extend.append(&other_prim);
+ prims_to_extend.append(&other_prim);
}
else {
- append.append(&other_prim);
+ prims_to_append.append(&other_prim);
}
}
- for (const UVPrimitive *other_prim : extend) {
+ for (const UVPrimitive *other_prim : prims_to_extend) {
extend_border(*other_prim);
}
- for (const UVPrimitive *other_prim : append) {
- primitives.append(*other_prim);
+ for (const UVPrimitive *other_prim : prims_to_append) {
+ append(*other_prim);
}
}
};
@@ -226,6 +233,149 @@ struct UVIslands {
}
};
+/* Bitmask containing the num of the nearest Island. */
+// TODO: this is a really quick implementation.
+struct UVIslandsMask {
+ float2 udim_offset;
+ ushort2 resolution;
+ Array<uint16_t> mask;
+
+ UVIslandsMask(float2 udim_offset, ushort2 resolution)
+ : udim_offset(udim_offset), resolution(resolution), mask(resolution.x * resolution.y)
+ {
+ clear();
+ }
+
+ void clear()
+ {
+ mask.fill(0xffff);
+ }
+
+ void add(const UVIslands &islands)
+ {
+ for (int index = 0; index < islands.islands.size(); index++) {
+ add(index, islands.islands[index]);
+ }
+ }
+
+ void add(short island_index, const UVIsland &island)
+ {
+ for (const UVPrimitive &prim : island.primitives) {
+ add(island_index, prim);
+ }
+ }
+
+ void add(short island_index, const UVPrimitive &primitive)
+ {
+ for (int i = 0; i < 3; i++) {
+ add(island_index, primitive.edges[i].vertices[0].uv);
+ }
+ }
+
+ void add(short island_index, const float2 uv)
+ {
+ float2 udim_corrected_uv = uv - udim_offset;
+ ushort2 mask_uv(udim_corrected_uv.x * resolution.x, udim_corrected_uv.y * resolution.y);
+ if (mask_uv.x < 0 || mask_uv.y < 0 || mask_uv.x >= resolution.x || mask_uv.y >= resolution.y) {
+ return;
+ }
+ uint64_t offset = resolution.x * mask_uv.y + mask_uv.x;
+ mask[offset] = island_index;
+ }
+
+ void dilate()
+ {
+ while (true) {
+ bool changed = dilate_x();
+ changed |= dilate_y();
+ if (!changed) {
+ break;
+ }
+ }
+ }
+
+ bool dilate_x()
+ {
+ bool changed = false;
+ const Array<uint16_t> prev_mask = mask;
+ for (int y = 0; y < resolution.y; y++) {
+ for (int x = 0; x < resolution.x; x++) {
+ uint64_t offset = y * resolution.x + x;
+ if (prev_mask[offset] != 0xffff) {
+ continue;
+ }
+ if (x != 0 && prev_mask[offset - 1] != 0xffff) {
+ mask[offset] = prev_mask[offset - 1];
+ changed = true;
+ }
+ else if (x < resolution.x && prev_mask[offset + 1] != 0xffff) {
+ mask[offset] = prev_mask[offset + 1];
+ changed = true;
+ }
+ }
+ }
+ return changed;
+ }
+
+ bool dilate_y()
+ {
+ bool changed = false;
+ const Array<uint16_t> prev_mask = mask;
+ for (int y = 0; y < resolution.y; y++) {
+ for (int x = 0; x < resolution.x; x++) {
+ uint64_t offset = y * resolution.x + x;
+ if (prev_mask[offset] != 0xffff) {
+ continue;
+ }
+ if (y != 0 && prev_mask[offset - resolution.x] != 0xffff) {
+ mask[offset] = prev_mask[offset - resolution.x];
+ changed = true;
+ }
+ else if (y < resolution.y && prev_mask[offset + resolution.x] != 0xffff) {
+ mask[offset] = prev_mask[offset + resolution.x];
+ changed = true;
+ }
+ }
+ }
+ return changed;
+ }
+
+ void print() const
+ {
+ int offset = 0;
+ for (int y = 0; y < resolution.y; y++) {
+ for (int x = 0; x < resolution.x; x++) {
+ uint16_t value = mask[offset++];
+ if (value == 0xffff) {
+ printf(" ");
+ }
+ else if (value == 0) {
+ printf("0");
+ }
+ else if (value == 1) {
+ printf("1");
+ }
+ else if (value == 2) {
+ printf("2");
+ }
+ else if (value == 3) {
+ printf("3");
+ }
+ else if (value == 4) {
+ printf("4");
+ }
+ else if (value == 5) {
+ printf("5");
+ }
+ else if (value == 6) {
+ printf("6");
+ }
+ }
+ printf("\n");
+ }
+ }
+};
+
void svg_header(std::ostream &ss)
{
ss << "<svg viewBox=\"0 0 1024 1024\" width=\"1024\" height=\"1024\" "
diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc
index 57667aa4518..c8e168e2301 100644
--- a/source/blender/blenkernel/intern/pbvh_pixels.cc
+++ b/source/blender/blenkernel/intern/pbvh_pixels.cc
@@ -38,6 +38,10 @@ constexpr bool USE_WATERTIGHT_CHECK = true;
static uv_islands::UVIslands build_uv_islands(const PBVH &pbvh, const MLoopUV *mloopuv)
{
uv_islands::UVIslands islands(pbvh.looptri, pbvh.totprim, mloopuv);
+ uv_islands::UVIslandsMask uv_masks(float2(0.0, 0.0), ushort2(1024, 1024));
+ uv_masks.add(islands);
+ uv_masks.dilate();
+ uv_masks.print();
return islands;
}