3D Texturing: Adding print_debug for visually inspecting the generated geometry.

During 3D texturing the uv islands are extended in order to fix seam bleeding
for manifold parts of the input mesh. This patch adds a `print_debug` method
on UVIsland that generates a python script. This script can be copy-past
into the Python Console to show the generated geometry.

This script can be extended to show the extracted border and use face colors
for showing internal decisions.
This commit is contained in:
Jeroen Bakker 2023-01-20 10:28:58 +01:00
parent 721bd5e6cf
commit 884e14ac93
3 changed files with 80 additions and 3 deletions

View File

@ -366,7 +366,11 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image
const VArraySpan<float2> uv_map = attributes.lookup<float2>(active_uv_name, ATTR_DOMAIN_CORNER);
uv_islands::MeshData mesh_data(
{pbvh->looptri, pbvh->totprim}, {pbvh->mloop, mesh->totloop}, pbvh->totvert, uv_map);
{pbvh->looptri, pbvh->totprim},
{pbvh->mloop, mesh->totloop},
pbvh->totvert,
uv_map,
{static_cast<blender::float3 *>(static_cast<void *>(pbvh->vert_positions)), pbvh->totvert});
uv_islands::UVIslands islands(mesh_data);
uv_islands::UVIslandsMask uv_masks;

View File

@ -210,11 +210,13 @@ static void mesh_data_init(MeshData &mesh_data)
MeshData::MeshData(const Span<MLoopTri> looptris,
const Span<MLoop> loops,
const int verts_num,
const Span<float2> uv_map)
const Span<float2> uv_map,
const Span<float3> vertex_positions)
: looptris(looptris),
verts_num(verts_num),
loops(loops),
uv_map(uv_map),
vertex_positions(vertex_positions),
vert_to_edge_map(verts_num),
edge_to_primitive_map(0),
primitive_to_edge_map(looptris.size())
@ -961,6 +963,63 @@ void UVIsland::extend_border(const MeshData &mesh_data,
}
}
void UVIsland::print_debug(const MeshData &mesh_data) const
{
std::stringstream ss;
ss << "#### Start UVIsland ####\n";
ss << "import bpy\n";
ss << "import bpy_extras.object_utils\n";
ss << "import mathutils\n";
ss << "uvisland_vertices = [\n";
for (const float3 &vertex_position : mesh_data.vertex_positions) {
ss << " mathutils.Vector((" << vertex_position.x << ", " << vertex_position.y << ", "
<< vertex_position.z << ")),\n";
}
ss << "]\n";
ss << "uvisland_edges = []\n";
ss << "uvisland_faces = [\n";
for (const VectorList<UVPrimitive>::UsedVector &uvprimitives : uv_primitives) {
for (const UVPrimitive &uvprimitive : uvprimitives) {
ss << " [" << uvprimitive.edges[0]->vertices[0]->vertex << ", "
<< uvprimitive.edges[0]->vertices[1]->vertex << ", "
<< uvprimitive
.get_other_uv_vertex(uvprimitive.edges[0]->vertices[0],
uvprimitive.edges[0]->vertices[1])
->vertex
<< "],\n";
}
}
ss << "]\n";
ss << "uvisland_uvs = [\n";
for (const VectorList<UVPrimitive>::UsedVector &uvprimitives : uv_primitives) {
for (const UVPrimitive &uvprimitive : uvprimitives) {
float2 uv = uvprimitive.edges[0]->vertices[0]->uv;
ss << " " << uv.x << ", " << uv.y << ",\n";
uv = uvprimitive.edges[0]->vertices[1]->uv;
ss << " " << uv.x << ", " << uv.y << ",\n";
uv = uvprimitive
.get_other_uv_vertex(uvprimitive.edges[0]->vertices[0],
uvprimitive.edges[0]->vertices[1])
->uv;
ss << " " << uv.x << ", " << uv.y << ",\n";
}
}
ss << "]\n";
ss << "uvisland_mesh = bpy.data.meshes.new(name='UVIsland')\n";
ss << "uvisland_mesh.from_pydata(uvisland_vertices, uvisland_edges, uvisland_faces)\n";
ss << "uv_map = uvisland_mesh.attributes.new('UVMap', 'FLOAT2', 'CORNER')\n";
ss << "uv_map.data.foreach_set('vector', uvisland_uvs)\n";
ss << "bpy_extras.object_utils.object_data_add(bpy.context, uvisland_mesh)\n";
ss << "#### End UVIsland ####\n\n\n";
std::cout << ss.str();
}
/** \} */
/* -------------------------------------------------------------------- */
@ -1289,6 +1348,14 @@ void UVIslands::extend_borders(const MeshData &mesh_data, const UVIslandsMask &i
ushort index = 0;
for (UVIsland &island : islands) {
island.extend_border(mesh_data, islands_mask, index++);
island.print_debug(mesh_data);
}
}
void UVIslands::print_debug(const MeshData &mesh_data) const
{
for (const UVIsland &island : islands) {
island.print_debug(mesh_data);
}
}

View File

@ -122,6 +122,7 @@ struct MeshData {
const int64_t verts_num;
const Span<MLoop> loops;
const Span<float2> uv_map;
const Span<float3> vertex_positions;
VertToEdgeMap vert_to_edge_map;
@ -142,7 +143,8 @@ struct MeshData {
explicit MeshData(Span<MLoopTri> looptris,
Span<MLoop> loops,
const int verts_num,
const Span<float2> uv_map);
const Span<float2> uv_map,
const Span<float3> vertex_positions);
};
struct UVVertex {
@ -312,6 +314,9 @@ struct UVIsland {
bool has_shared_edge(const UVPrimitive &primitive) const;
bool has_shared_edge(const MeshData &mesh_data, const int primitive_i) const;
void extend_border(const UVPrimitive &primitive);
/** Print a python script to the console that generates a mesh representing this UVIsland. */
void print_debug(const MeshData &mesh_data) const;
};
struct UVIslands {
@ -321,6 +326,7 @@ struct UVIslands {
void extract_borders();
void extend_borders(const MeshData &mesh_data, const UVIslandsMask &islands_mask);
void print_debug(const MeshData &mesh_data) const;
};
/** Mask to find the index of the UVIsland for a given UV coordinate. */