303 lines
7.2 KiB
C
303 lines
7.2 KiB
C
#undef UFBXT_TEST_GROUP
|
|
#define UFBXT_TEST_GROUP "topology"
|
|
|
|
#if UFBXT_IMPL
|
|
void ufbxt_check_generated_normals(ufbx_mesh *mesh, ufbxt_diff_error *err, size_t expected_normals)
|
|
{
|
|
ufbx_topo_edge *topo = calloc(mesh->num_indices, sizeof(ufbx_topo_edge));
|
|
ufbxt_assert(topo);
|
|
|
|
ufbx_compute_topology(mesh, topo, mesh->num_indices);
|
|
|
|
uint32_t *normal_indices = calloc(mesh->num_indices, sizeof(uint32_t));
|
|
size_t num_normals = ufbx_generate_normal_mapping(mesh, topo, mesh->num_indices, normal_indices, mesh->num_indices, false);
|
|
|
|
if (expected_normals > 0) {
|
|
ufbxt_assert(num_normals == expected_normals);
|
|
}
|
|
|
|
ufbx_vec3 *normals = calloc(num_normals, sizeof(ufbx_vec3));
|
|
ufbx_compute_normals(mesh, &mesh->vertex_position, normal_indices, mesh->num_indices, normals, num_normals);
|
|
|
|
ufbx_vertex_vec3 new_normals = { 0 };
|
|
new_normals.exists = true;
|
|
new_normals.values.data = normals;
|
|
new_normals.values.count = num_normals;
|
|
new_normals.indices.data = normal_indices;
|
|
new_normals.indices.count = mesh->num_indices;
|
|
|
|
for (size_t i = 0; i < mesh->num_indices; i++) {
|
|
ufbx_vec3 fn = ufbx_get_vertex_vec3(&mesh->vertex_normal, i);
|
|
ufbx_vec3 rn = ufbx_get_vertex_vec3(&new_normals, i);
|
|
|
|
ufbxt_assert_close_vec3(err, fn, rn);
|
|
}
|
|
|
|
free(normals);
|
|
free(normal_indices);
|
|
free(topo);
|
|
}
|
|
#endif
|
|
|
|
UFBXT_FILE_TEST(maya_edge_smoothing)
|
|
#if UFBXT_IMPL
|
|
{
|
|
ufbx_node *node = ufbx_find_node(scene, "pCube1");
|
|
ufbxt_assert(node && node->mesh);
|
|
ufbx_mesh *mesh = node->mesh;
|
|
ufbxt_check_generated_normals(mesh, err, 16);
|
|
}
|
|
#endif
|
|
|
|
UFBXT_FILE_TEST(maya_no_smoothing)
|
|
#if UFBXT_IMPL
|
|
{
|
|
ufbx_node *node = ufbx_find_node(scene, "pCube1");
|
|
ufbxt_assert(node && node->mesh);
|
|
ufbx_mesh *mesh = node->mesh;
|
|
ufbxt_check_generated_normals(mesh, err, 16);
|
|
}
|
|
#endif
|
|
|
|
UFBXT_FILE_TEST(maya_planar_ngon)
|
|
#if UFBXT_IMPL
|
|
{
|
|
ufbx_node *node = ufbx_find_node(scene, "pDisc1");
|
|
ufbxt_assert(node && node->mesh);
|
|
ufbx_mesh *mesh = node->mesh;
|
|
ufbxt_check_generated_normals(mesh, err, 0);
|
|
}
|
|
#endif
|
|
|
|
UFBXT_FILE_TEST(maya_subsurf_cube)
|
|
#if UFBXT_IMPL
|
|
{
|
|
}
|
|
#endif
|
|
|
|
UFBXT_FILE_TEST(maya_subsurf_plane)
|
|
#if UFBXT_IMPL
|
|
{
|
|
}
|
|
#endif
|
|
|
|
UFBXT_FILE_TEST(maya_subsurf_cube_crease)
|
|
#if UFBXT_IMPL
|
|
{
|
|
}
|
|
#endif
|
|
|
|
UFBXT_FILE_TEST(blender_293_suzanne_subsurf)
|
|
#if UFBXT_IMPL
|
|
{
|
|
}
|
|
#endif
|
|
|
|
UFBXT_FILE_TEST_ALT(subsurf_alloc_fail, maya_subsurf_cube)
|
|
#if UFBXT_IMPL
|
|
{
|
|
ufbx_node *node = ufbx_find_node(scene, "pCube1");
|
|
ufbxt_assert(node && node->mesh);
|
|
ufbx_mesh *mesh = node->mesh;
|
|
|
|
for (size_t max_temp = 1; max_temp < 10000; max_temp++) {
|
|
ufbx_subdivide_opts opts = { 0 };
|
|
opts.temp_allocator.huge_threshold = 1;
|
|
opts.temp_allocator.allocation_limit = max_temp;
|
|
|
|
ufbxt_hintf("Temp limit: %zu", max_temp);
|
|
|
|
ufbx_error error;
|
|
ufbx_mesh *sub_mesh = ufbx_subdivide_mesh(mesh, 2, &opts, &error);
|
|
if (sub_mesh) {
|
|
ufbxt_logf(".. Tested up to %zu temporary allocations", max_temp);
|
|
ufbx_free_mesh(sub_mesh);
|
|
break;
|
|
}
|
|
ufbxt_assert(error.type == UFBX_ERROR_ALLOCATION_LIMIT);
|
|
}
|
|
|
|
for (size_t max_result = 1; max_result < 10000; max_result++) {
|
|
ufbx_subdivide_opts opts = { 0 };
|
|
opts.result_allocator.huge_threshold = 1;
|
|
opts.result_allocator.allocation_limit = max_result;
|
|
|
|
ufbxt_hintf("Result limit: %zu", max_result);
|
|
|
|
ufbx_error error;
|
|
ufbx_mesh *sub_mesh = ufbx_subdivide_mesh(mesh, 2, &opts, &error);
|
|
if (sub_mesh) {
|
|
ufbxt_logf(".. Tested up to %zu result allocations", max_result);
|
|
ufbx_free_mesh(sub_mesh);
|
|
break;
|
|
}
|
|
ufbxt_assert(error.type == UFBX_ERROR_ALLOCATION_LIMIT);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
UFBXT_FILE_TEST(blender_293_suzanne_subsurf_uv)
|
|
#if UFBXT_IMPL
|
|
{
|
|
}
|
|
#endif
|
|
|
|
UFBXT_FILE_TEST(blender_293x_nonmanifold_subsurf)
|
|
#if UFBXT_IMPL
|
|
{
|
|
}
|
|
#endif
|
|
|
|
UFBXT_FILE_TEST(blender_293_ngon_subsurf)
|
|
#if UFBXT_IMPL
|
|
{
|
|
}
|
|
#endif
|
|
|
|
UFBXT_FILE_TEST(blender_293x_subsurf_boundary)
|
|
#if UFBXT_IMPL
|
|
{
|
|
}
|
|
#endif
|
|
|
|
UFBXT_FILE_TEST(blender_293x_subsurf_max_crease)
|
|
#if UFBXT_IMPL
|
|
{
|
|
ufbx_mesh *mesh = (ufbx_mesh*)ufbx_find_element(scene, UFBX_ELEMENT_MESH, "Plane");
|
|
ufbx_mesh *subdivided = ufbx_subdivide_mesh(mesh, 1, NULL, NULL);
|
|
|
|
for (size_t i = 0; i < mesh->num_edges; i++) {
|
|
ufbxt_assert_close_real(err, mesh->edge_crease.data[i], 1.0f);
|
|
}
|
|
|
|
size_t num_edge = 0;
|
|
size_t num_center = 0;
|
|
for (size_t i = 0; i < subdivided->num_edges; i++) {
|
|
ufbx_edge edge = subdivided->edges.data[i];
|
|
ufbx_vec3 a = ufbx_get_vertex_vec3(&subdivided->vertex_position, edge.a);
|
|
ufbx_vec3 b = ufbx_get_vertex_vec3(&subdivided->vertex_position, edge.b);
|
|
ufbx_real a_len = a.x*a.x + a.y*a.y + a.z*a.z;
|
|
ufbx_real b_len = b.x*b.x + b.y*b.y + b.z*b.z;
|
|
|
|
if (a_len < 0.01f || b_len < 0.01f) {
|
|
ufbxt_assert_close_real(err, subdivided->edge_crease.data[i], 0.0f);
|
|
num_center++;
|
|
} else {
|
|
ufbxt_assert_close_real(err, subdivided->edge_crease.data[i], 1.0f);
|
|
num_edge++;
|
|
}
|
|
}
|
|
|
|
ufbxt_assert(num_edge == 8);
|
|
ufbxt_assert(num_center == 4);
|
|
|
|
ufbx_free_mesh(subdivided);
|
|
}
|
|
#endif
|
|
|
|
UFBXT_FILE_TEST(maya_subsurf_max_crease)
|
|
#if UFBXT_IMPL
|
|
{
|
|
ufbx_node *node = ufbx_find_node(scene, "pCube1");
|
|
ufbxt_assert(node && node->mesh);
|
|
ufbx_mesh *subdivided = ufbx_subdivide_mesh(node->mesh, 1, NULL, NULL);
|
|
ufbxt_assert(subdivided);
|
|
|
|
size_t num_top = 0;
|
|
size_t num_bottom = 0;
|
|
for (size_t i = 0; i < subdivided->num_edges; i++) {
|
|
ufbx_edge edge = subdivided->edges.data[i];
|
|
ufbx_vec3 a = ufbx_get_vertex_vec3(&subdivided->vertex_position, edge.a);
|
|
ufbx_vec3 b = ufbx_get_vertex_vec3(&subdivided->vertex_position, edge.b);
|
|
ufbx_real a_len = a.x*a.x + a.z*a.z;
|
|
ufbx_real b_len = b.x*b.x + b.z*b.z;
|
|
|
|
if (a.y < -0.49f && b.y < -0.49f && a_len > 0.01f && b_len > 0.01f) {
|
|
ufbxt_assert_close_real(err, subdivided->edge_crease.data[i], 0.8f);
|
|
num_bottom++;
|
|
} else if (a.y > +0.49f && b.y > +0.49f && a_len > 0.01f && b_len > 0.01f) {
|
|
ufbxt_assert_close_real(err, subdivided->edge_crease.data[i], 1.0f);
|
|
num_top++;
|
|
} else {
|
|
ufbxt_assert_close_real(err, subdivided->edge_crease.data[i], 0.0f);
|
|
}
|
|
a = a;
|
|
}
|
|
|
|
ufbxt_assert(num_top == 8);
|
|
ufbxt_assert(num_bottom == 8);
|
|
|
|
ufbx_free_mesh(subdivided);
|
|
}
|
|
#endif
|
|
|
|
UFBXT_FILE_TEST(maya_subsurf_3x_cube)
|
|
#if UFBXT_IMPL
|
|
{
|
|
}
|
|
#endif
|
|
|
|
UFBXT_FILE_TEST(maya_subsurf_3x_cube_crease)
|
|
#if UFBXT_IMPL
|
|
{
|
|
}
|
|
#endif
|
|
|
|
#if UFBXT_IMPL
|
|
typedef struct {
|
|
ufbx_vec3 position;
|
|
ufbx_vec3 normal;
|
|
} ufbxt_vertex_pn;
|
|
#endif
|
|
|
|
UFBXT_FILE_TEST(blender_293_half_smooth_cube)
|
|
#if UFBXT_IMPL
|
|
{
|
|
ufbx_node *node = ufbx_find_node(scene, "Cube");
|
|
ufbxt_assert(node && node->mesh);
|
|
ufbx_mesh *mesh = node->mesh;
|
|
ufbxt_assert(mesh->num_indices == 6*4);
|
|
ufbxt_assert(mesh->num_triangles == 6*2);
|
|
|
|
ufbxt_vertex_pn vertices[36];
|
|
uint32_t indices[36];
|
|
size_t num_indices = 0;
|
|
|
|
uint32_t tri[64];
|
|
for (size_t fi = 0; fi < mesh->num_faces; fi++) {
|
|
size_t num_tris = ufbx_triangulate_face(tri, 64, mesh, mesh->faces.data[fi]);
|
|
for (size_t ti = 0; ti < num_tris * 3; ti++) {
|
|
vertices[num_indices].position = ufbx_get_vertex_vec3(&mesh->vertex_position, tri[ti]);
|
|
vertices[num_indices].normal = ufbx_get_vertex_vec3(&mesh->vertex_normal, tri[ti]);
|
|
num_indices++;
|
|
}
|
|
}
|
|
|
|
ufbx_vertex_stream stream = { vertices, sizeof(ufbxt_vertex_pn) };
|
|
size_t num_vertices = ufbx_generate_indices(&stream, 1, indices, num_indices, NULL, NULL);
|
|
ufbxt_assert(num_vertices == 12);
|
|
|
|
}
|
|
#endif
|
|
|
|
UFBXT_FILE_TEST(maya_vertex_crease_single)
|
|
#if UFBXT_IMPL
|
|
{
|
|
}
|
|
#endif
|
|
|
|
|
|
UFBXT_FILE_TEST(maya_vertex_crease)
|
|
#if UFBXT_IMPL
|
|
{
|
|
}
|
|
#endif
|
|
|
|
UFBXT_FILE_TEST(blender_312x_vertex_crease)
|
|
#if UFBXT_IMPL
|
|
{
|
|
}
|
|
#endif
|
|
|
|
|