Revision: 72365
          http://sourceforge.net/p/brlcad/code/72365
Author:   starseeker
Date:     2019-02-07 15:00:02 +0000 (Thu, 07 Feb 2019)
Log Message:
-----------
checkpoint

Modified Paths:
--------------
    brlcad/trunk/src/libged/mater.cxx

Modified: brlcad/trunk/src/libged/mater.cxx
===================================================================
--- brlcad/trunk/src/libged/mater.cxx   2019-02-07 08:00:39 UTC (rev 72364)
+++ brlcad/trunk/src/libged/mater.cxx   2019-02-07 15:00:02 UTC (rev 72365)
@@ -33,7 +33,9 @@
 
 #include <string.h>
 
-static const char *usage = "mater [-s] object_name shader r [g b] inherit\n    
          -m  density_file [map_file]";
+static const char *usage = "Usage: mater [-s] object_name shader r [g b] 
inherit\n"
+                           "              -m  density_file [map_file]\n"
+                           "              -m  --names-from-ids density_file\n";
 
 int
 _ged_mater_shader(struct ged *gedp, int argc, const char *argv[])
@@ -57,7 +59,7 @@
 
     /* must be wanting help */
     if (argc == 1) {
-       bu_vls_printf(gedp->ged_result_str, "Usage: %s", usage);
+       bu_vls_printf(gedp->ged_result_str, "%s", usage);
        return GED_HELP;
     }
 
@@ -111,7 +113,7 @@
 
     /* too much */
     if ((!offset && argc > 7) || (offset && argc > 5)) {
-       bu_vls_printf(gedp->ged_result_str, "Too many arguments.\nUsage: %s", 
usage);
+       bu_vls_printf(gedp->ged_result_str, "Too many arguments.\n%s", usage);
        return GED_ERROR;
     }
 
@@ -239,7 +241,7 @@
 }
 
 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)
+_ged_read_msmap(struct ged *gedp, const char *mbuff, std::set<std::string> 
&defined_materials, std::map<std::string,std::string> &listed_to_defined)
 {
     int ret = GED_OK;
     std::string mb(mbuff);
@@ -289,17 +291,15 @@
            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()) {
+           if (listed_to_defined.find(m1) != listed_to_defined.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()) {
+           if (defined_materials.find(m2) == defined_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));
+           listed_to_defined.insert(std::pair<std::string, std::string>(m1, 
m2));
        }
     }
     return ret;
@@ -308,6 +308,7 @@
 int
 _ged_mater_mat_id(struct ged *gedp, int argc, const char *argv[])
 {
+    int names_from_ids = 0;
     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;
@@ -315,11 +316,20 @@
     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;
+    std::map<int, std::string> d2n;
+    std::set<std::string> listed_materials;
+    std::set<std::string> defined_materials;
+    std::set<std::string> g_materials;
+    std::map<std::string,std::string> listed_to_defined;
 
+    if (BU_STR_EQUAL(argv[1], "--names-from-ids")) {
+       argv[1] = argv[0];
+       argc--; argv++;
+       names_from_ids = 1;
+    }
+
     if (argc < 2 || argc > 3) {
-       bu_vls_printf(gedp->ged_result_str, "Usage: %s", usage);
+       bu_vls_printf(gedp->ged_result_str, "%s", usage);
        return GED_OK;
     }
     if (!bu_file_exists(argv[1], NULL)) {
@@ -326,11 +336,16 @@
        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)) {
+    if (argc == 3 && names_from_ids) {
+       bu_vls_printf(gedp->ged_result_str, "Warning - only the density file is 
used mapping from material ids to names, ignoring %s", argv[2]);
+    }
+    if (argc == 3 && !names_from_ids && !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;
     }
 
+    /* OK, we know what we're doing - start reading inputs */
+
     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]);
@@ -352,10 +367,14 @@
                    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));
+               defined_materials.insert(std::string(densities[idx].name));
                bu_free(densities[idx].name, "free density name");
            }
        }
+       std::map<std::string, int>::iterator n2d_it;
+       for (n2d_it = n2d.begin(); n2d_it != n2d.end(); n2d_it++) {
+           d2n[n2d_it->second] = n2d_it->first;
+       }
        bu_free(densities, "density_entry array");
        bu_close_mapped_file(dfile);
        if (found_duplicate) {
@@ -363,7 +382,13 @@
        }
     }
 
-    if (argc == 3) {
+    // For simplicity, let the complex -> simple map know to map known 
materials to themselves
+    std::set<std::string>::iterator s_it;
+    for (s_it = defined_materials.begin(); s_it != defined_materials.end(); 
s_it++) {
+       listed_to_defined.insert(std::pair<std::string, std::string>(*s_it, 
*s_it));
+    }
+
+    if (argc == 3 && !names_from_ids) {
        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]);
@@ -371,13 +396,107 @@
        }
     }
     if (mfile) {
+       /* Populate the complex name -> simple name map from the mapping file, 
if we have one. */
        mbuff = (char *)(mfile->buf);
-       if (_ged_read_msmap(gedp, mbuff, known_materials, complex_to_known) !=  
GED_OK) {
+       if (_ged_read_msmap(gedp, mbuff, defined_materials, listed_to_defined) 
!=  GED_OK) {
            bu_vls_printf(gedp->ged_result_str, "error reading material 
simplification mapping file %s", argv[2]);
            return GED_ERROR;
        }
     }
 
+    // Find the objects we need to work with (if any)
+    const char *mname_search = "-attr material_name";
+    const char *mid_search = "-attr material_id";
+    struct bu_ptbl mn_objs = BU_PTBL_INIT_ZERO;
+    struct bu_ptbl id_objs = BU_PTBL_INIT_ZERO;
+    std::set<struct directory *> mns, ids;
+    db_update_nref(gedp->ged_wdbp->dbip, &rt_uniresource);
+    (void)db_search(&mn_objs, DB_SEARCH_FLAT|DB_SEARCH_RETURN_UNIQ_DP, 
mname_search, 0, NULL, gedp->ged_wdbp->dbip, NULL);
+    (void)db_search(&id_objs, DB_SEARCH_FLAT|DB_SEARCH_RETURN_UNIQ_DP, 
mid_search, 0, NULL, gedp->ged_wdbp->dbip, NULL);
+    for(size_t i = 0; i < BU_PTBL_LEN(&mn_objs); i++) {
+       struct directory *d = (struct directory *)BU_PTBL_GET(&mn_objs, i);
+       mns.insert(d);
+    }
+    for(size_t i = 0; i < BU_PTBL_LEN(&id_objs); i++) {
+       struct directory *d = (struct directory *)BU_PTBL_GET(&mn_objs, i);
+       ids.insert(d);
+    }
+    db_search_free(&mn_objs); 
+    db_search_free(&id_objs); 
+
+
+    if (names_from_ids) {
+       std::set<struct directory *>::iterator d_it;
+       for (d_it = ids.begin(); d_it != ids.end(); d_it++) {
+           struct directory *dp = *d_it; 
+           struct bu_attribute_value_set avs;
+           bu_avs_init_empty(&avs);
+           if (db5_get_attributes(gedp->ged_wdbp->dbip, &avs, dp)) {
+               bu_vls_printf(gedp->ged_result_str, "Cannot get attributes for 
object %s\n", dp->d_namep);
+               return GED_ERROR;
+           }
+           const char *mat_id = bu_avs_get(&avs, "material_id");
+           const char *oname = bu_avs_get(&avs, "material_name");
+           std::string nname = d2n[std::stoi(mat_id)];
+           if (oname && nname.compare(std::string(oname))) {
+               (void)bu_avs_add(&avs, "material_name", nname.c_str());
+               if (db5_update_attributes(dp, &avs, gedp->ged_wdbp->dbip)) {
+                   bu_vls_printf(gedp->ged_result_str, "Error: failed to 
update object %s attributes\n", dp->d_namep);
+                   bu_avs_free(&avs);
+                   return GED_ERROR;
+               }
+           } else {
+               // Already has correct name, no need to update
+               bu_avs_free(&avs);
+           }
+       }
+       return GED_OK;
+    } else {
+       std::set<struct directory *> ids_wo_names;
+       std::set<struct directory *>::iterator d_it;
+       for (d_it = ids.begin(); d_it != ids.end(); d_it++) {
+           if (mns.find(*d_it) == mns.end()) {
+               ids_wo_names.insert(*d_it);
+           }
+       }
+       if (ids_wo_names.size()) {
+           bu_vls_printf(gedp->ged_result_str, "Warning - the following 
object(s) have a material_id attribute but no material_name attribute (use the 
\"--names_from_ids\" option to assign them names using a density file):\n");
+           for (d_it = ids.begin(); d_it != ids.end(); d_it++) {
+               bu_vls_printf(gedp->ged_result_str, "%s\n", (*d_it)->d_namep);
+           }
+       }
+    }
+
+    std::set<struct directory *>::iterator dp_it;
+    for (dp_it = mns.begin(); dp_it != mns.end(); dp_it++) {
+       struct directory *dp = *dp_it; 
+       struct bu_attribute_value_set avs;
+       bu_avs_init_empty(&avs);
+       if (db5_get_attributes(gedp->ged_wdbp->dbip, &avs, dp)) {
+           bu_vls_printf(gedp->ged_result_str, "Cannot get attributes for 
object %s\n", dp->d_namep);
+           return GED_ERROR;
+       }
+       const char *mat_id = bu_avs_get(&avs, "material_id");
+       const char *oname = bu_avs_get(&avs, "material_name");
+       if (listed_to_defined.find(std::string(oname)) == 
listed_to_defined.end()) {
+           bu_vls_printf(gedp->ged_result_str, "Warning - unknown material %s 
found on object %s\n", oname, dp->d_namep);
+           continue;
+       }
+
+       int nid = n2d[listed_to_defined[std::string(oname)]];
+       if (std::stoi(mat_id) != nid) {
+           (void)bu_avs_add(&avs, "material_id", std::to_string(nid).c_str());
+           if (db5_update_attributes(dp, &avs, gedp->ged_wdbp->dbip)) {
+               bu_vls_printf(gedp->ged_result_str, "Error: failed to update 
object %s attributes\n", dp->d_namep);
+               bu_avs_free(&avs);
+               return GED_ERROR;
+           }
+       } else {
+           // Already has correct name, no need to update
+           bu_avs_free(&avs);
+       }
+    }
+
     return GED_OK;
 }
 
@@ -393,7 +512,7 @@
 
     /* must be wanting help */
     if (argc == 1) {
-       bu_vls_printf(gedp->ged_result_str, "Usage: %s", usage);
+       bu_vls_printf(gedp->ged_result_str, "%s", usage);
        return GED_HELP;
     }
 

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

Reply via email to