WIP: uv-simple-select #1

Closed
Chris Blackbourn wants to merge 182 commits from uv-simple-select into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
2 changed files with 70 additions and 15 deletions
Showing only changes of commit 3120bfa0fc - Show all commits

View File

@ -152,21 +152,67 @@ static void geom_add_uv_vertex(const char *p, const char *end, GlobalVertices &r
r_global_vertices.uv_vertices.append(uv); r_global_vertices.uv_vertices.append(uv);
} }
static void geom_add_edge(Geometry *geom, /**
const char *p, * Parse vertex index and transform to non-negative, zero-based.
const char *end, * Sets r_index to the index or INT32_MAX on error.
GlobalVertices &r_global_vertices) * Index is transformed and bounds-checked using n_vertices,
* which specifies the number of vertices that have been read before.
* Returns updated p.
*/
static const char *parse_vertex_index(const char *p, const char *end, size_t n_elems, int &r_index)
{ {
int edge_v1, edge_v2; p = parse_int(p, end, INT32_MAX, r_index, false);
p = parse_int(p, end, -1, edge_v1); if (r_index != INT32_MAX) {
p = parse_int(p, end, -1, edge_v2); r_index += r_index < 0 ? n_elems : -1;
/* Always keep stored indices non-negative and zero-based. */ if (r_index < 0 || r_index >= n_elems) {
edge_v1 += edge_v1 < 0 ? r_global_vertices.vertices.size() : -1; fprintf(stderr, "Invalid vertex index %i (valid range [0, %zu))\n", r_index, n_elems);
edge_v2 += edge_v2 < 0 ? r_global_vertices.vertices.size() : -1; r_index = INT32_MAX;
BLI_assert(edge_v1 >= 0 && edge_v2 >= 0); }
geom->edges_.append({uint(edge_v1), uint(edge_v2)}); }
geom->track_vertex_index(edge_v1); return p;
geom->track_vertex_index(edge_v2); }
/**
* Parse a polyline and add its line segments as loose edges.
* We support the following polyline specifications:
* - "l v1/vt1 v2/vt2 ..."
* - "l v1 v2 ..."
* If a line only has one vertex (technically not allowed by the spec),
* no line is created, but the vertex will be added to
* the mesh even if it is unconnected.
*/
static void geom_add_polyline(Geometry *geom,
const char *p,
const char *end,
GlobalVertices &r_global_vertices)
{
int last_vertex_index;
p = drop_whitespace(p, end);
p = parse_vertex_index(p, end, r_global_vertices.vertices.size(), last_vertex_index);
if (last_vertex_index == INT32_MAX) {
fprintf(stderr, "Skipping invalid OBJ polyline.\n");
return;
}
geom->track_vertex_index(last_vertex_index);
while (p < end) {
int vertex_index;
/* Lines can contain texture coordinate indices, just ignore them. */
p = drop_non_whitespace(p, end);
/* Skip whitespace to get to the next vertex. */
p = drop_whitespace(p, end);
p = parse_vertex_index(p, end, r_global_vertices.vertices.size(), vertex_index);
if (vertex_index == INT32_MAX) {
break;
}
geom->edges_.append({uint(last_vertex_index), uint(vertex_index)});
geom->track_vertex_index(vertex_index);
last_vertex_index = vertex_index;
}
} }
static void geom_add_polygon(Geometry *geom, static void geom_add_polygon(Geometry *geom,
@ -548,7 +594,7 @@ void OBJParser::parse(Vector<std::unique_ptr<Geometry>> &r_all_geometries,
} }
/* Faces. */ /* Faces. */
else if (parse_keyword(p, end, "l")) { else if (parse_keyword(p, end, "l")) {
geom_add_edge(curr_geom, p, end, r_global_vertices); geom_add_polyline(curr_geom, p, end, r_global_vertices);
} }
/* Objects. */ /* Objects. */
else if (parse_keyword(p, end, "o")) { else if (parse_keyword(p, end, "o")) {

View File

@ -869,4 +869,13 @@ TEST_F(obj_importer_test, import_split_options_none)
import_and_check("split_options.obj", expect, std::size(expect), 0); import_and_check("split_options.obj", expect, std::size(expect), 0);
} }
TEST_F(obj_importer_test, import_polylines)
{
Expectation expect[] = {
{"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)},
{"OBpolylines", OB_MESH, 13, 8, 0, 0, float3(1, 0, 0), float3(.7, .7, 2)},
};
import_and_check("polylines.obj", expect, std::size(expect), 0);
}
} // namespace blender::io::obj } // namespace blender::io::obj