static const char* __tstl__test_stl_read_multi_solid( const char* filepath, unsigned expected_solid_count) { FILE* infile = fopen(filepath, "rb"); if (infile != NULL) { unsigned solid_count = 0; int error = GMIO_ERROR_OK; struct gmio_stream stream = gmio_stream_stdio(infile); struct gmio_stl_read_options roptions = {0}; struct gmio_stl_mesh_creator null_creator = {0}; roptions.func_stla_get_streamsize = gmio_stla_infos_probe_streamsize; while (gmio_no_error(error) && !gmio_stream_at_end(&stream)) { error = gmio_stl_read(&stream, &null_creator, &roptions); if (gmio_no_error(error)) ++solid_count; } fclose(infile); UTEST_ASSERT(gmio_no_error(error)); UTEST_COMPARE_UINT(expected_solid_count, solid_count); } else { perror(NULL); UTEST_FAIL(""); } return NULL; }
static const char* test_stlb_header_write() { const char* filepath = "temp/solid.stlb"; struct gmio_stlb_header header = {0}; const char* header_str = "temp/solid.stlb generated with gmio library"; { FILE* outfile = fopen(filepath, "wb"); struct gmio_stream stream = gmio_stream_stdio(outfile); memcpy(&header, header_str, GMIO_MIN(GMIO_STLB_HEADER_SIZE, strlen(header_str))); const int error = gmio_stlb_header_write( &stream, GMIO_ENDIANNESS_LITTLE, &header, 0); fclose(outfile); UTEST_COMPARE_INT(GMIO_ERROR_OK, error); } { struct gmio_stl_data data = {0}; struct gmio_stl_mesh_creator creator = gmio_stl_data_mesh_creator(&data); const int error = gmio_stl_read_file(filepath, &creator, NULL); UTEST_COMPARE_INT(GMIO_ERROR_OK, error); UTEST_ASSERT(gmio_stlb_header_equal(&header, &data.header)); UTEST_COMPARE_UINT(0, data.tri_array.count); } return NULL; }
/* * ut_lookup is simple test function that should validate all possible * lookup cases. Saying "all possible cases" I mean that given function * should generate 100% coverage of ttree_lookup code. */ UTEST_FUNCTION(ut_lookup, args) { Ttree tree; TtreeNode *tnode; int num_keys, num_items, ret, i; struct balance_info binfo; struct item *item; num_keys = utest_get_arg(args, 0, INT); num_items = utest_get_arg(args, 1, INT); UTEST_ASSERT(num_items >= 1); ret = ttree_init(&tree, num_keys, true, __cmpfunc, struct item, key); UTEST_ASSERT(ret >= 0); for (i = 0; i < (num_items / 2); i++) { item = alloc_item(i); UTEST_ASSERT(ttree_insert(&tree, item) == 0); item = alloc_item(num_items - i - 1); UTEST_ASSERT(ttree_insert(&tree, item) == 0); } check_tree_balance(&tree, &binfo); if (binfo.balance != TREE_BALANCED) { UTEST_FAILED("Tree is unbalanced on a node %p BFC = %d, %s\n", binfo.tnode, binfo.tnode->bfc, balance_name(binfo.balance)); } /* * Just an example of how to browse the tree keys * in a sorted order: from the smallest one to the greatest one. * The following cycle runs from the smallest key to the greatest * one and checks that an item by given key can be successfully found. */ tnode = ttree_node_leftmost(tree.root); while (tnode) { tnode_for_each_index(tnode, i) { ret = *(int *)tnode_key(tnode, i); item = (struct item *)ttree_lookup(&tree, &ret, NULL); CHECK_ITEM(item, ret); } tnode = tnode->successor; }
static const char* test_stla_write() { const char* model_filepath = filepath_stlb_grabcad_arm11; const char* model_filepath_out = "temp/solid.stla"; struct gmio_stl_data data = {0}; char header_str[GMIO_STLB_HEADER_SIZE + 1] = {0}; /* Read input model file */ { struct gmio_stl_mesh_creator creator = gmio_stl_data_mesh_creator(&data); const int error = gmio_stl_read_file(model_filepath, &creator, NULL); UTEST_COMPARE_INT(GMIO_ERROR_OK, error); } /* Write the model to STL ascii format */ { struct gmio_stl_write_options opts = {0}; const struct gmio_stl_mesh mesh = gmio_stl_data_mesh(&data); gmio_stlb_header_to_printable_str(&data.header, header_str, '_'); opts.stla_solid_name = header_str; opts.stla_float32_prec = 7; opts.stla_float32_format = GMIO_FLOAT_TEXT_FORMAT_SHORTEST_LOWERCASE; const int error = gmio_stl_write_file( GMIO_STL_FORMAT_ASCII, model_filepath_out, &mesh, &opts); UTEST_COMPARE_INT(GMIO_ERROR_OK, error); } /* Read the output STL ascii model */ { char trim_header_str[sizeof(header_str)] = {0}; struct gmio_stl_data data_stla = {0}; struct gmio_stl_mesh_creator creator = gmio_stl_data_mesh_creator(&data_stla); gmio_cstr_copy( trim_header_str, sizeof(trim_header_str), header_str, sizeof(header_str)); gmio_string_trim_from_end(trim_header_str, sizeof(header_str)); const int error = gmio_stl_read_file(model_filepath_out, &creator, NULL); UTEST_COMPARE_INT(GMIO_ERROR_OK, error); UTEST_COMPARE_UINT(data.tri_array.count, data_stla.tri_array.count); UTEST_COMPARE_CSTR(trim_header_str, data_stla.solid_name); for (size_t i = 0; i < data.tri_array.count; ++i) { const struct gmio_stl_triangle* lhs = &data.tri_array.ptr[i]; const struct gmio_stl_triangle* rhs = &data_stla.tri_array.ptr[i]; const bool tri_equal = gmio_stl_triangle_equal(lhs, rhs, 5); UTEST_ASSERT(tri_equal); } } return NULL; }
static const char* test_stlb_write() { const char* model_fpath = filepath_stlb_grabcad_arm11; const char* model_fpath_out = "temp/solid.le_stlb"; const char* model_fpath_out_be = "temp/solid.be_stlb"; struct gmio_stl_data data = {0}; /* Read input model file */ { struct gmio_stl_mesh_creator creator = gmio_stl_data_mesh_creator(&data); const int error = gmio_stl_read_file(model_fpath, &creator, NULL); UTEST_COMPARE_INT(GMIO_ERROR_OK, error); } /* Write back input model file * Write also the model file in big-endian STL format */ { const struct gmio_stl_mesh mesh = gmio_stl_data_mesh(&data); struct gmio_stl_write_options opts = {0}; opts.stlb_header = data.header; int error = gmio_stl_write_file( GMIO_STL_FORMAT_BINARY_LE, model_fpath_out, &mesh, &opts); UTEST_COMPARE_INT(GMIO_ERROR_OK, error); /* Big-endian version */ error = gmio_stl_write_file( GMIO_STL_FORMAT_BINARY_BE, model_fpath_out_be, &mesh, &opts); UTEST_COMPARE_INT(GMIO_ERROR_OK, error); } /* Check input and output models are equal */ { uint8_t buffer_in[2048] = {0}; uint8_t buffer_out[2048] = {0}; const size_t buff_size = 2048; size_t bytes_read_in = 0; size_t bytes_read_out = 0; FILE* in = fopen(model_fpath, "rb"); FILE* out = fopen(model_fpath_out, "rb"); if (in == NULL || out == NULL) { __tstl__fclose_2(in, out); perror("test_stlb_write()"); UTEST_FAIL("fopen() error for in/out model files"); } do { bytes_read_in = fread(buffer_in, 1, buff_size, in); bytes_read_out = fread(buffer_out, 1, buff_size, out); if (bytes_read_in != bytes_read_out) { __tstl__fclose_2(in, out); UTEST_FAIL("Different byte count between in/out"); } if (memcmp(buffer_in, buffer_out, buff_size) != 0) { __tstl__fclose_2(in, out); UTEST_FAIL("Different buffer contents between in/out"); } } while (!feof(in) && !feof(out) && bytes_read_in > 0 && bytes_read_out > 0); __tstl__fclose_2(in, out); } /* Check output LE/BE models are equal */ { struct gmio_stl_data data_be = {0}; struct gmio_stl_mesh_creator creator = gmio_stl_data_mesh_creator(&data_be); const int error = gmio_stl_read_file(model_fpath_out_be, &creator, NULL); UTEST_COMPARE_INT(GMIO_ERROR_OK, error); UTEST_ASSERT(gmio_stlb_header_equal(&data.header, &data_be.header)); UTEST_COMPARE_UINT(data.tri_array.count, data_be.tri_array.count); UTEST_ASSERT(memcmp(data.tri_array.ptr, data_be.tri_array.ptr, data.tri_array.count * sizeof(struct gmio_stl_triangle)) == 0); free(data_be.tri_array.ptr); } free(data.tri_array.ptr); return NULL; }