Revision: 72362 http://sourceforge.net/p/brlcad/code/72362 Author: starseeker Date: 2019-02-06 22:49:37 +0000 (Wed, 06 Feb 2019) Log Message: ----------- checkpoint
Modified Paths: -------------- brlcad/trunk/include/analyze.h brlcad/trunk/src/libanalyze/api.c brlcad/trunk/src/libanalyze/density.c brlcad/trunk/src/libanalyze/tests/density.c brlcad/trunk/src/libged/gqa.c brlcad/trunk/src/libged/mater.cxx Modified: brlcad/trunk/include/analyze.h =================================================================== --- brlcad/trunk/include/analyze.h 2019-02-06 20:26:56 UTC (rev 72361) +++ brlcad/trunk/include/analyze.h 2019-02-06 22:49:37 UTC (rev 72362) @@ -150,7 +150,7 @@ */ ANALYZE_EXPORT extern int parse_densities_buffer(char *buf, size_t len, - struct density_entry *densities, + struct density_entry **densities, struct bu_vls *result_str, int *num_densities); Modified: brlcad/trunk/src/libanalyze/api.c =================================================================== --- brlcad/trunk/src/libanalyze/api.c 2019-02-06 20:26:56 UTC (rev 72361) +++ brlcad/trunk/src/libanalyze/api.c 2019-02-06 22:49:37 UTC (rev 72362) @@ -522,7 +522,7 @@ sret = fread(buf, sb.st_size, 1, fp); if (sret != 1) perror("fread"); - ret = parse_densities_buffer(buf, (unsigned long)sb.st_size, state->densities, NULL, &state->num_densities); + ret = parse_densities_buffer(buf, (unsigned long)sb.st_size, &(state->densities), NULL, &state->num_densities); bu_free(buf, "density buffer"); fclose(fp); @@ -570,7 +570,7 @@ */ buf = (char *)bu_malloc(bu->count+1, "density buffer"); memcpy(buf, bu->u.int8, bu->count); - ret = parse_densities_buffer(buf, bu->count, state->densities, NULL, &state->num_densities); + ret = parse_densities_buffer(buf, bu->count, &(state->densities), NULL, &state->num_densities); bu_free((void *)buf, "density buffer"); return ret; Modified: brlcad/trunk/src/libanalyze/density.c =================================================================== --- brlcad/trunk/src/libanalyze/density.c 2019-02-06 20:26:56 UTC (rev 72361) +++ brlcad/trunk/src/libanalyze/density.c 2019-02-06 22:49:37 UTC (rev 72362) @@ -25,11 +25,13 @@ #include "analyze.h" int -parse_densities_buffer(char *buf, size_t len, struct density_entry *densities, struct bu_vls *result_str, int *num_densities) +parse_densities_buffer(char *obuf, size_t len, struct density_entry **densities, struct bu_vls *result_str, int *num_densities) { char *p, *q, *last; long idx; double density; + char *buf = (char *)bu_malloc(sizeof(char)*len+1, "buffer copy"); + memcpy(buf, obuf, len); buf[len] = '\0'; last = &buf[len]; @@ -62,11 +64,13 @@ idx = strtol(p, &q, 10); if (q == (char *)NULL) { + bu_free(buf, "free buf copy"); bu_vls_printf(result_str, "could not convert idx\n"); return ANALYZE_ERROR; } if (idx < 0) { + bu_free(buf, "free buf copy"); bu_vls_printf(result_str, "bad density index (%ld < 0)\n", idx); return ANALYZE_ERROR; } @@ -73,11 +77,13 @@ density = strtod(q, &p); if (q == p) { + bu_free(buf, "free buf copy"); bu_vls_printf(result_str, "could not convert density\n"); return ANALYZE_ERROR; } if (density < 0.0) { + bu_free(buf, "free buf copy"); bu_vls_printf(result_str, "bad density (%lf < 0)\n", density); return ANALYZE_ERROR; } @@ -94,17 +100,17 @@ q = last; while (idx >= *num_densities) { - densities = (struct density_entry *)bu_realloc(densities, sizeof(struct density_entry)*(*num_densities)*2, + *densities = (struct density_entry *)bu_realloc(*densities, sizeof(struct density_entry)*(*num_densities)*2, "density entries"); *num_densities *= 2; } - densities[idx].magic = DENSITY_MAGIC; + (*densities)[idx].magic = DENSITY_MAGIC; /* since BRL-CAD does computation in mm, but the table is in * grams / (cm^3) we convert the table on input */ - densities[idx].grams_per_cu_mm = density / 1000.0; - densities[idx].name = bu_strdup(p); + (*densities)[idx].grams_per_cu_mm = density / 1000.0; + (*densities)[idx].name = bu_strdup(p); p = q; @@ -114,13 +120,14 @@ #ifdef PRINT_DENSITIES for (idx = 0; idx < *num_densities; idx++) - if (densities[idx].magic == DENSITY_MAGIC) + if ((*densities)[idx].magic == DENSITY_MAGIC) bu_vls_printf(&_ged_current_gedp->ged_result_str, "%4d %6g %s\n", idx, - densities[idx].grams_per_cu_mm, - densities[idx].name); + (*densities)[idx].grams_per_cu_mm, + (*densities)[idx].name); #endif + bu_free(buf, "free buf copy"); return ANALYZE_OK; } Modified: brlcad/trunk/src/libanalyze/tests/density.c =================================================================== --- brlcad/trunk/src/libanalyze/tests/density.c 2019-02-06 20:26:56 UTC (rev 72361) +++ brlcad/trunk/src/libanalyze/tests/density.c 2019-02-06 22:49:37 UTC (rev 72362) @@ -60,7 +60,7 @@ densities = (struct density_entry *)bu_calloc(num_densities, sizeof(struct density_entry), "density entries"); - ret = parse_densities_buffer(buf, (unsigned long)sb.st_size, densities, NULL, &num_densities); + ret = parse_densities_buffer(buf, (unsigned long)sb.st_size, &densities, NULL, &num_densities); for (i = 0; i < num_densities; i++) { if (densities[i].name) Modified: brlcad/trunk/src/libged/gqa.c =================================================================== --- brlcad/trunk/src/libged/gqa.c 2019-02-06 20:26:56 UTC (rev 72361) +++ brlcad/trunk/src/libged/gqa.c 2019-02-06 22:49:37 UTC (rev 72362) @@ -779,7 +779,7 @@ sret = fread(buf, sb.st_size, 1, fp); if (sret != 1) perror("fread"); - ret = parse_densities_buffer(buf, (unsigned long)sb.st_size, densities, _ged_current_gedp->ged_result_str, &num_densities); + ret = parse_densities_buffer(buf, (unsigned long)sb.st_size, &densities, _ged_current_gedp->ged_result_str, &num_densities); bu_free(buf, "density buffer"); fclose(fp); @@ -828,7 +828,7 @@ */ buf = (char *)bu_malloc(bu->count+1, "density buffer"); memcpy(buf, bu->u.int8, bu->count); - ret = parse_densities_buffer(buf, bu->count, densities, _ged_current_gedp->ged_result_str, &num_densities); + ret = parse_densities_buffer(buf, bu->count, &densities, _ged_current_gedp->ged_result_str, &num_densities); bu_free((void *)buf, "density buffer"); return ret; Modified: brlcad/trunk/src/libged/mater.cxx =================================================================== --- brlcad/trunk/src/libged/mater.cxx 2019-02-06 20:26:56 UTC (rev 72361) +++ brlcad/trunk/src/libged/mater.cxx 2019-02-06 22:49:37 UTC (rev 72362) @@ -23,16 +23,22 @@ * */ +#include <map> +#include <set> +#include <string> +#include <sstream> + +#include "analyze.h" #include "ged.h" #include <string.h> +static const char *usage = "mater [-s] object_name shader r [g b] inherit\n -m density_file [map_file]"; int -ged_mater(struct ged *gedp, int argc, const char *argv[]) +_ged_mater_shader(struct ged *gedp, int argc, const char *argv[]) { struct bu_attribute_value_set avs; - static const char *usage = "object_name shader r [g b] inherit"; static const char *prompt[] = { "Name of combination to edit? ", /* unused */ "Specify shader. Enclose spaces within quotes. E.g., \"light invisible=1\"\nShader? ('del' to delete, '.' to skip) ", @@ -49,16 +55,9 @@ struct bu_vls vls = BU_VLS_INIT_ZERO; int offset = 0; - GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); - GED_CHECK_READ_ONLY(gedp, GED_ERROR); - GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); - - /* initialize result */ - bu_vls_trunc(gedp->ged_result_str, 0); - /* must be wanting help */ if (argc == 1) { - bu_vls_printf(gedp->ged_result_str, "Usage: %s %s", argv[0], usage); + bu_vls_printf(gedp->ged_result_str, "Usage: %s", usage); return GED_HELP; } @@ -112,7 +111,7 @@ /* too much */ if ((!offset && argc > 7) || (offset && argc > 5)) { - bu_vls_printf(gedp->ged_result_str, "Too many arguments.\nUsage: %s %s", argv[0], usage); + bu_vls_printf(gedp->ged_result_str, "Too many arguments.\nUsage: %s", usage); return GED_ERROR; } @@ -239,13 +238,189 @@ return GED_OK; } +int +_ged_read_msmap(struct ged *gedp, const char *mbuff, std::set<std::string> &known_materials, std::map<std::string,std::string> &complex_to_known) +{ + int ret = GED_OK; + std::string mb(mbuff); + std::istringstream ss(mb); + std::string line; + std::string ws("\t "); + std::string ws2("\t \""); + std::string tc("\""); + std::string sep("\t ,;:\"="); + while (std::getline(ss, line)) { + size_t curr_char = 0; + std::string m1, m2; + while (line[curr_char] && (ws.find(line[curr_char]) != std::string::npos)) curr_char++; + if (line[curr_char] == '"') { + curr_char++; + // In first name and quoted, go until matching quote found + while (line[curr_char] && line[curr_char] != '"') { + m1.push_back(line[curr_char]); + curr_char++; + } + } else { + // In first name and not quoted, go until we find a non-sep character + while (line[curr_char] && (sep.find(line[curr_char]) == std::string::npos)) { + m1.push_back(line[curr_char]); + curr_char++; + } + } + // Eat the spacer chars + while (line[curr_char] && (sep.find(line[curr_char]) != std::string::npos)) curr_char++; + // In second name + if (curr_char > 0 && line[curr_char-1] == '"') { + while (line[curr_char] && (tc.find(line[curr_char]) == std::string::npos)) { + m2.push_back(line[curr_char]); + curr_char++; + } + } else { + while (line[curr_char] && (ws2.find(line[curr_char]) == std::string::npos)) { + m2.push_back(line[curr_char]); + curr_char++; + } + } + if (!m1.length() && !m2.length()) { + continue; + } + if (!m1.length() || !m2.length()) { + bu_vls_printf(gedp->ged_result_str, "%s -> %s: invalid specifier in mapping file", m1.c_str(), m2.c_str()); + ret = GED_ERROR; + } else { + // Have names, process + bu_log("m1: %s", m1.c_str()); + bu_log("m2: %s", m2.c_str()); + if (complex_to_known.find(m1) != complex_to_known.end()) { + bu_vls_printf(gedp->ged_result_str, "%s is multiply defined in the mapping file", m1.c_str()); + ret = GED_ERROR; + } + if (known_materials.find(m2) == known_materials.end()) { + bu_vls_printf(gedp->ged_result_str, "%s is not known in the density file", m2.c_str()); + ret = GED_ERROR; + } + complex_to_known.insert(std::pair<std::string, std::string>(m1, m2)); + } + } + return ret; +} -/* - * Local Variables: - * tab-width: 8 - * mode: C - * indent-tabs-mode: t - * c-file-style: "stroustrup" - * End: - * ex: shiftwidth=4 tabstop=8 - */ +int +_ged_mater_mat_id(struct ged *gedp, int argc, const char *argv[]) +{ + int num_densities = 128; + struct density_entry *densities = (struct density_entry *)bu_calloc(num_densities, sizeof(struct density_entry), "density entries"); + struct bu_mapped_file *dfile = NULL; + char *dbuff = NULL; + struct bu_mapped_file *mfile = NULL; + char *mbuff = NULL; + std::map<std::string, int> n2d; + std::set<std::string> known_materials; + std::map<std::string,std::string> complex_to_known; + + if (argc < 2 || argc > 3) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s", usage); + return GED_OK; + } + if (!bu_file_exists(argv[1], NULL)) { + bu_vls_printf(gedp->ged_result_str, "density file %s not found", argv[1]); + return GED_ERROR; + } + if (argc == 3 && !bu_file_exists(argv[2], NULL)) { + bu_vls_printf(gedp->ged_result_str, "material simplification mapping file %s not found", argv[1]); + return GED_ERROR; + } + + dfile = bu_open_mapped_file(argv[1], "densities file"); + if (!dfile) { + bu_vls_printf(gedp->ged_result_str, "could not open density file %s", argv[1]); + return GED_ERROR; + } + + dbuff = (char *)(dfile->buf); + if (parse_densities_buffer(dbuff, dfile->buflen, &densities, NULL, &num_densities) != ANALYZE_OK) { + bu_vls_printf(gedp->ged_result_str, "could not parse density file %s", argv[1]); + bu_close_mapped_file(dfile); + return GED_ERROR; + } else { + /* Populate the name->material_id map from the density file */ + int found_duplicate = 0; + for (int idx = 0; idx < num_densities; idx++) { + if (densities[idx].magic == DENSITY_MAGIC) { + if (n2d.find(std::string(densities[idx].name)) != n2d.end()) { + found_duplicate = 1; + bu_vls_printf(gedp->ged_result_str, "density file contains multiple densities for %s", densities[idx].name); + } + n2d[std::string(densities[idx].name)] = idx; + known_materials.insert(std::string(densities[idx].name)); + bu_free(densities[idx].name, "free density name"); + } + } + bu_free(densities, "density_entry array"); + bu_close_mapped_file(dfile); + if (found_duplicate) { + return GED_ERROR; + } + } + + if (argc == 3) { + mfile = bu_open_mapped_file(argv[2], "material simplification mapping file"); + if (!mfile) { + bu_vls_printf(gedp->ged_result_str, "could not open material simplification mapping file %s", argv[2]); + return GED_ERROR; + } + } + if (mfile) { + mbuff = (char *)(mfile->buf); + if (_ged_read_msmap(gedp, mbuff, known_materials, complex_to_known) != GED_OK) { + bu_vls_printf(gedp->ged_result_str, "error reading material simplification mapping file %s", argv[2]); + return GED_ERROR; + } + } + + return GED_OK; +} + +int +ged_mater(struct ged *gedp, int argc, const char *argv[]) +{ + GED_CHECK_DATABASE_OPEN(gedp, GED_ERROR); + GED_CHECK_READ_ONLY(gedp, GED_ERROR); + GED_CHECK_ARGC_GT_0(gedp, argc, GED_ERROR); + + /* initialize result */ + bu_vls_trunc(gedp->ged_result_str, 0); + + /* must be wanting help */ + if (argc == 1) { + bu_vls_printf(gedp->ged_result_str, "Usage: %s", usage); + return GED_HELP; + } + + /* The -s option allows us to do mater on an object even in the unlikely + * even the object is named "-m" */ + if (BU_STR_EQUAL(argv[1], "-s")) { + argv[1] = argv[0]; + argc--; argv++; + return _ged_mater_shader(gedp, argc, argv); + } + + if (BU_STR_EQUAL(argv[1], "-m")) { + argv[1] = argv[0]; + argc--; argv++; + return _ged_mater_mat_id(gedp, argc, argv); + } + + /* If we aren't instructed to do a mapping, proceed with normal behavior */ + return _ged_mater_shader(gedp, argc, argv); +} + +// Local Variables: +// tab-width: 8 +// mode: C++ +// c-basic-offset: 4 +// indent-tabs-mode: t +// c-file-style: "stroustrup" +// End: +// ex: shiftwidth=4 tabstop=8 + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. _______________________________________________ BRL-CAD Source Commits mailing list brlcad-commits@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/brlcad-commits