Revision: 71597
          http://sourceforge.net/p/brlcad/code/71597
Author:   starseeker
Date:     2018-08-28 18:03:20 +0000 (Tue, 28 Aug 2018)
Log Message:
-----------
checkpoint

Modified Paths:
--------------
    brlcad/trunk/src/libged/facetize.c

Modified: brlcad/trunk/src/libged/facetize.c
===================================================================
--- brlcad/trunk/src/libged/facetize.c  2018-08-28 17:37:09 UTC (rev 71596)
+++ brlcad/trunk/src/libged/facetize.c  2018-08-28 18:03:20 UTC (rev 71597)
@@ -48,10 +48,69 @@
 #define SOLID_OBJ_NAME 1
 #define COMB_OBJ_NAME 2
 
+#define GED_FACETIZE_NULL  0x0
 #define GED_FACETIZE_NMGBOOL  0x1
 #define GED_FACETIZE_SPSR  0x2
 #define GED_FACETIZE_CONTINUATION  0x4
 
+#define GED_FACETIZE_SUCCESS 0
+#define GED_FACETIZE_FAILURE 1
+#define GED_FACETIZE_FAILURE_PNTGEN 2
+#define GED_FACETIZE_FAILURE_PNTBBOX 3
+#define GED_FACETIZE_FAILURE_BOTBBOX 4
+#define GED_FACETIZE_FAILURE_BOTINVALID 5
+#define GED_FACETIZE_FAILURE_DECIMATION 6
+#define GED_FACETIZE_FAILURE_NMG 7
+#define GED_FACETIZE_FAILURE_CONTINUATION_SURFACE 10
+
+
+struct _ged_facetize_report_info {
+    double feature_size;
+    double avg_thickness;
+    double obj_bbox_vol;
+    double pnts_bbox_vol;
+    double bot_bbox_vol;
+    int failure_mode;
+};
+
+void
+_ged_facetize_failure_msg(struct bu_vls *msg, int type, const char *prefix, 
struct _ged_facetize_report_info *r)
+{
+    if (!msg) return;
+    switch (type) {
+       case GED_FACETIZE_SUCCESS:
+           bu_vls_printf(msg, "%s: success\n", prefix);
+           break;
+       case GED_FACETIZE_FAILURE:
+           bu_vls_printf(msg, "%s: unknown failure\n", prefix);
+           break;
+       case GED_FACETIZE_FAILURE_PNTGEN:
+           bu_vls_printf(msg, "%s: point generation failed.\n", prefix);
+           break;
+       case GED_FACETIZE_FAILURE_PNTBBOX:
+           bu_vls_printf(msg, "%s: object bbox volume (%g) is widely different 
than the sampled point cloud bbox volume (%g).\n", prefix, r->obj_bbox_vol, 
r->pnts_bbox_vol);
+           break;
+       case GED_FACETIZE_FAILURE_BOTBBOX:
+           bu_vls_printf(msg, "%s: BoT bbox volume (%g) is widely different 
than the sampled point cloud bbox volume (%g).\n", prefix, r->bot_bbox_vol, 
r->pnts_bbox_vol);
+           break;
+       case GED_FACETIZE_FAILURE_BOTINVALID:
+           bu_vls_printf(msg, "%s: unable to create a valid BoT.\n", prefix);
+           break;
+       case GED_FACETIZE_FAILURE_DECIMATION:
+           bu_vls_printf(msg, "%s: decimation of mesh failed.\n", prefix);
+           break;
+       case GED_FACETIZE_FAILURE_NMG:
+           bu_vls_printf(msg, "%s: unable to successfully generate NMG 
object\n", prefix);
+           break;
+       case GED_FACETIZE_FAILURE_CONTINUATION_SURFACE:
+           bu_vls_printf(msg, "%s: continuation polygonization surface build 
failed.\n", prefix);
+           break;
+       default:
+           return;
+           break;
+    }
+}
+
 struct _ged_facetize_opts {
 
     int quiet;
@@ -94,6 +153,11 @@
     int stderr_stashed;
     int serr;
     int fnull;
+
+    struct bu_vls *froot;
+    struct bu_vls *nmg_comb;
+    struct bu_vls *continuation_comb;
+    struct bu_vls *spsr_comb;
 };
 
 struct _ged_facetize_opts * _ged_facetize_opts_create()
@@ -143,6 +207,19 @@
     BU_GET(o->nmg_log_header, struct bu_vls);
     bu_vls_init(o->nmg_log_header);
 
+
+    BU_GET(o->froot, struct bu_vls);
+    bu_vls_init(o->froot);
+
+    BU_GET(o->nmg_comb, struct bu_vls);
+    bu_vls_init(o->nmg_comb);
+
+    BU_GET(o->continuation_comb, struct bu_vls);
+    bu_vls_init(o->continuation_comb);
+
+    BU_GET(o->spsr_comb, struct bu_vls);
+    bu_vls_init(o->spsr_comb);
+
     return o;
 }
 void _ged_facetize_opts_destroy(struct _ged_facetize_opts *o)
@@ -169,6 +246,19 @@
     BU_PUT(o->nmg_log, struct bu_vls);
     BU_PUT(o->nmg_log_header, struct bu_vls);
 
+
+    bu_vls_free(o->froot);
+    BU_PUT(o->froot, struct bu_vls);
+
+    bu_vls_free(o->nmg_comb);
+    BU_PUT(o->nmg_comb, struct bu_vls);
+
+    bu_vls_free(o->continuation_comb);
+    BU_PUT(o->continuation_comb, struct bu_vls);
+
+    bu_vls_free(o->spsr_comb);
+    BU_PUT(o->spsr_comb, struct bu_vls);
+
     BU_PUT(o, struct _ged_facetize_opts);
 }
 
@@ -189,6 +279,18 @@
     return 0;
 }
 
+HIDDEN double
+_bbox_vol(point_t b_min, point_t b_max)
+{
+    double bbox_vol = 0.0;
+    fastf_t b_xlen, b_ylen, b_zlen;
+    b_xlen = fabs(b_max[X] - b_min[X]);
+    b_ylen = fabs(b_max[Y] - b_min[Y]);
+    b_zlen = fabs(b_max[Z] - b_min[Z]);
+    bbox_vol = b_xlen * b_ylen * b_zlen;
+    return bbox_vol; 
+}
+
 HIDDEN void
 _rt_pnts_bbox(point_t rpp_min, point_t rpp_max, struct rt_pnts_internal *pnts)
 {
@@ -203,6 +305,7 @@
     }
 }
 
+
 HIDDEN void
 _pnts_bbox(point_t rpp_min, point_t rpp_max, int pnt_cnt, point_t *pnts)
 {
@@ -215,40 +318,7 @@
     }
 }
 
-/* Check the volume of the bounding box of the vertices of a BoT against the
- * bounding box of a point cloud - a large difference means something
- * probably isn't right.  For the moment, use >50% difference. */
-HIDDEN int
-_ged_facetize_pnts_array_compare(int pnt_cnt, point_t *pnts_array, struct 
rt_pnts_internal *pnts, const char *method)
-{
 
-    point_t p_min, p_max;
-    point_t b_min, b_max;
-    fastf_t p_xlen, p_ylen, p_zlen;
-    fastf_t b_xlen, b_ylen, b_zlen;
-    fastf_t pvol, bvol, delta_vol;
-    _rt_pnts_bbox(p_min, p_max, pnts);
-    _pnts_bbox(b_min, b_max, pnt_cnt, pnts_array);
-#if 0
-    bu_log("pnts bbox: %g %g %g, %g %g %g\n", V3ARGS(p_min), V3ARGS(p_max));
-    bu_log("bot  bbox: %g %g %g, %g %g %g\n", V3ARGS(b_min), V3ARGS(b_max));
-#endif
-    p_xlen = fabs(p_max[X] - p_min[X]);
-    p_ylen = fabs(p_max[Y] - p_min[Y]);
-    p_zlen = fabs(p_max[Z] - p_min[Z]);
-    pvol = p_xlen * p_ylen * p_zlen;
-    b_xlen = fabs(b_max[X] - b_min[X]);
-    b_ylen = fabs(b_max[Y] - b_min[Y]);
-    b_zlen = fabs(b_max[Z] - b_min[Z]);
-    bvol = b_xlen * b_ylen * b_zlen;
-    delta_vol = fabs(pvol - bvol);
-    if (delta_vol > pvol * 0.5) {
-       bu_log("%s: Warning, BoT bbox volume (%g) is widely different than the 
sampled point cloud bbox volume (%g).\n", method, bvol, pvol);
-    }
-    return GED_OK;
-}
-
-
 HIDDEN int
 _ged_facetize_bomb_hook(void *cdata, void *str)
 {
@@ -943,9 +1013,8 @@
     return ret;
 }
 
-
 HIDDEN int
-_ged_continuation_obj(int *is_valid, struct ged *gedp, const char *objname, 
const char *newname, struct _ged_facetize_opts *opts)
+_ged_continuation_obj(struct _ged_facetize_report_info *r, struct ged *gedp, 
const char *objname, const char *newname, struct _ged_facetize_opts *opts)
 {
     int first_run = 1;
     int fatal_error_cnt = 0;
@@ -952,9 +1021,11 @@
     int ret = GED_OK;
     double avg_thickness = 0.0;
     double min_len = 0.0;
-    fastf_t feature_size, target_feature_size;
+    fastf_t feature_size = 0.0;
+    fastf_t target_feature_size = 0.0;
     int face_cnt = 0;
     double prev_feat_size;
+    double successful_feature_size;
     double xlen, ylen, zlen;
     struct directory *dp;
     struct db_i *dbip = gedp->ged_wdbp->dbip;
@@ -974,6 +1045,9 @@
 
     dp = db_lookup(dbip, objname, LOOKUP_QUIET);
 
+    if (!r) return GED_ERROR;
+    r->failure_mode = GED_FACETIZE_SUCCESS;
+
     if (rt_db_get_internal(&in_intern, dp, dbip, (fastf_t *)NULL, 
&rt_uniresource) < 0) {
        if (opts->verbosity) {
            bu_log("Error: could not determine type of object %s, skipping\n", 
objname);
@@ -986,6 +1060,7 @@
        return GED_ERROR;
     }
 
+
     BU_ALLOC(pnts, struct rt_pnts_internal);
     pnts->magic = RT_PNTS_INTERNAL_MAGIC;
     pnts->scale = 0.0;
@@ -1011,15 +1086,27 @@
     }
 
     /* Shoot - we need both the avg thickness of the hit partitions and seed 
points */
-    if (analyze_obj_to_pnts(pnts, &avg_thickness, gedp->ged_wdbp->dbip, 
objname, &btol, flags, max_pnts, opts->max_time) ||
-           pnts->count <= 0) {
-       if (!opts->quiet) {
-           bu_log("Continuation Method: point generation failed: %s\n", 
objname);
-       }
+    if (analyze_obj_to_pnts(pnts, &avg_thickness, gedp->ged_wdbp->dbip, 
objname, &btol, flags, max_pnts, opts->max_time) || pnts->count <= 0) {
+       r->failure_mode = GED_FACETIZE_FAILURE_PNTGEN;
        ret = GED_ERROR;
        goto ged_facetize_continuation_memfree;
     }
 
+    /* Check the volume of the bounding box of the BoT against the bounding box
+     * of the point cloud - a large difference means something probably isn't
+     * right.  For the moment, use >50% difference. */
+    {
+       point_t p_min, p_max;
+       _rt_pnts_bbox(p_min, p_max, pnts);
+       r->pnts_bbox_vol = _bbox_vol(p_min, p_max);
+       r->obj_bbox_vol = _bbox_vol(rpp_min, rpp_max);
+       if (fabs(r->pnts_bbox_vol - r->obj_bbox_vol) > r->pnts_bbox_vol * 0.5) {
+           ret = GED_ERROR;
+           r->failure_mode = GED_FACETIZE_FAILURE_PNTBBOX;
+           goto ged_facetize_continuation_memfree;
+       }
+    }
+
     if (opts->verbosity) {
        bu_log("Continuation Method: average raytrace thickness: %g\n", 
avg_thickness);
     }
@@ -1059,9 +1146,9 @@
     pn = BU_LIST_PNEXT(pnt_normal, pl);
     feature_size = 2*avg_thickness;
     prev_feat_size = feature_size;
-    while (!polygonize_failure && (feature_size > 0.5*target_feature_size || 
face_cnt < 1000) && fatal_error_cnt < 3) {
+    while (!polygonize_failure && (feature_size > 0.9*target_feature_size || 
face_cnt < 1000) && fatal_error_cnt < 4) {
        double timestamp = bu_gettime();
-       double delta;
+       int delta;
        fastf_t *verts = bot->vertices;
        int *faces = bot->faces;
        int num_faces = bot->num_faces;
@@ -1074,7 +1161,13 @@
                    feature_size, pn->v, objname, gedp->ged_wdbp->dbip, 
opts->max_time, opts->verbosity);
        if (polygonize_failure) {
            if (!opts->quiet && polygonize_failure == 2) {
-               bu_log("Continuation Method timed out after %d seconds with 
size %g\n", opts->max_time, feature_size);
+               bu_log("Continuation Method: timed out after %d seconds with 
size %g\n", opts->max_time, feature_size);
+               /* If we still haven't had a successful run, back the feature 
size out and try again */
+               if (first_run) {
+                   feature_size = feature_size * 1.5;
+                   fatal_error_cnt++;
+                   continue;
+               }
            }
            bot->faces = faces;
            bot->vertices = verts;
@@ -1085,32 +1178,39 @@
                 * unless we've had multiple fatal errors. */
                polygonize_failure = 0;
                prev_feat_size = feature_size;
-               delta = (bu_gettime() - timestamp)/1e6;
                if (!opts->quiet) {
-                   bu_log("Continuation Method fatal error at size %g\n", 
opts->max_time, feature_size);
+                   bu_log("Continuation Method: error at size %g\n", 
feature_size);
                }
-               feature_size = feature_size * ((!first_run) ? 0.95 : 0.1);
+               /* If we've had a successful first run, just nudge the feature
+                * size down and retry.  If we haven't succeeded yet, and we've
+                * got just this one error, try dropping the feature size down 
by an order
+                * of magnitude.  If we haven't succeed yet *and* we've got
+                * multiple fatal errors, try dropping it by half. */
+               feature_size = feature_size * ((!first_run) ? 0.95 : 
((fatal_error_cnt) ? 0.5 : 0.1));
+               if (!opts->quiet) {
+                   bu_log("Continuation Method: retrying with size %g\n", 
feature_size);
+               }
                fatal_error_cnt++;
-               first_run = 0;
                continue;
            }
-           feature_size = prev_feat_size;
+           feature_size = successful_feature_size;
            if (!opts->quiet && bot->faces) {
-               bu_log("Continuation Method: using last successful BoT with %d 
faces, feature size %g\n", bot->num_faces, feature_size);
+               bu_log("Continuation Method: unable to polygonize at target 
size (%g), using last successful BoT with %d faces, feature size %g\n", 
target_feature_size, bot->num_faces, successful_feature_size);
            }
        } else {
-           if (!opts->quiet) {
-               bu_log("Continuation Method succeeded with size %g\n", 
opts->max_time, feature_size);
-           }
            if (verts) bu_free(verts, "old verts");
            if (faces) bu_free(faces, "old faces");
-           /* if we have a fatal error, decrement on subsequent success */
+           /* if we have had a fatal error in the past, decrement on 
subsequent success */
            if (fatal_error_cnt) {
                fatal_error_cnt--;
            }
            prev_feat_size = feature_size;
-           delta = (bu_gettime() - timestamp)/1e6;
-           feature_size = feature_size * ((delta < 5.0) ? 0.7 : 0.9);
+           successful_feature_size = feature_size;
+           delta = (int)((bu_gettime() - timestamp)/1e6);
+           if (!opts->quiet) {
+               bu_log("Continuation Method: succeeded in %d seconds with size 
%g\n", delta, feature_size);
+           }
+           feature_size = feature_size * ((delta < 5) ? 0.7 : 0.9);
            face_cnt = bot->num_faces;
        }
        first_run = 0;
@@ -1124,6 +1224,7 @@
        if (!opts->quiet) {
            bu_log("Continuation Method: surface reconstruction failed: %s\n", 
objname);
        }
+       r->failure_mode = GED_FACETIZE_FAILURE_CONTINUATION_SURFACE;
        ret = GED_ERROR;
        goto ged_facetize_continuation_memfree;
     }
@@ -1132,15 +1233,19 @@
     if (opts->feat_perc > 0) {
        struct rt_bot_internal *obot = bot;
 
-       if (!opts->quiet) {
+       if (opts->verbosity) {
            bu_log("Continuation Method: decimating with feature size %g\n", 
1.5*feature_size);
        }
 
        bot = _try_decimate(bot, 1.5*feature_size, opts);
 
-       if (bot == obot && opts->verbosity) {
-           bu_log("Continuation Method: decimation failed, returning original 
BoT (may be large)\n");
-       } 
+       if (bot == obot) {
+           r->failure_mode = GED_FACETIZE_FAILURE_DECIMATION;
+           if (bot->vertices) bu_free(bot->vertices, "verts");
+           if (bot->faces) bu_free(bot->faces, "verts");
+           ret = GED_ERROR;
+           goto ged_facetize_continuation_memfree;
+       }
        if (bot != obot && !opts->quiet) {
            bu_log("Continuation Method: decimation succeeded, final BoT has %d 
faces\n", bot->num_faces);
        }
@@ -1149,16 +1254,28 @@
     /* Check the volume of the bounding box of the BoT against the bounding box
      * of the point cloud - a large difference means something probably isn't
      * right.  For the moment, use >50% difference. */
-    ret = _ged_facetize_pnts_array_compare(bot->num_vertices, (point_t 
*)bot->vertices, pnts, "Continuation Method");
-    if (ret == GED_ERROR) {;
-       goto ged_facetize_continuation_memfree;
+    {
+       point_t b_min, b_max;
+       _pnts_bbox(b_min, b_max, bot->num_vertices, (point_t *)bot->vertices);
+       r->bot_bbox_vol = _bbox_vol(b_min, b_max);
+       if (fabs(r->pnts_bbox_vol - r->bot_bbox_vol) > r->pnts_bbox_vol * 0.5) {
+           ret = GED_ERROR;
+           r->failure_mode = GED_FACETIZE_FAILURE_BOTBBOX;
+           if (bot->vertices) bu_free(bot->vertices, "verts");
+           if (bot->faces) bu_free(bot->faces, "verts");
+           goto ged_facetize_continuation_memfree;
+       }
     }
 
-    if (is_valid) {
+    /* Check validity - do not return an invalid BoT */
+    {
        int is_v = !bg_trimesh_solid(bot->num_vertices, bot->num_faces, 
(fastf_t *)bot->vertices, (int *)bot->faces, NULL);
-       (*is_valid) = is_v;
-       if (!is_v && !opts->quiet) {
-           bu_log("Continuation Method: created invalid bot: %s\n", objname);
+       if (!is_v) {
+           r->failure_mode = GED_FACETIZE_FAILURE_BOTINVALID;
+           if (bot->vertices) bu_free(bot->vertices, "verts");
+           if (bot->faces) bu_free(bot->faces, "verts");
+           ret = GED_ERROR;
+           goto ged_facetize_continuation_memfree;
        }
     }
 
@@ -1169,7 +1286,7 @@
     } else {
        /* Convert BoT to NMG */
        struct model *m = nmg_mm();
-       struct nmgregion *r;
+       struct nmgregion *nr;
        struct rt_db_internal intern;
 
        /* Use intern to fake out rt_bot_tess, since it expects an
@@ -1178,12 +1295,10 @@
        intern.idb_major_type = DB5_MAJORTYPE_BRLCAD;
        intern.idb_type = ID_BOT;
        intern.idb_ptr = (void *)bot;
-       if (rt_bot_tess(&r, m, &intern, NULL, &btol) < 0) {
-           if (!opts->quiet) {
-               bu_log("Continuation Method: failed to convert BoT to NMG: 
%s\n", objname);
-           }
+       if (rt_bot_tess(&nr, m, &intern, NULL, &btol) < 0) {
            rt_db_free_internal(&intern);
            ret = GED_ERROR;
+           r->failure_mode = GED_FACETIZE_FAILURE_NMG;
            goto ged_facetize_continuation_memfree;
        } else {
            /* OK,have NMG now - write it out */
@@ -1193,6 +1308,9 @@
     }
 
 ged_facetize_continuation_memfree:
+    r->feature_size = feature_size;
+    r->avg_thickness = avg_thickness;
+
     if (free_pnts && pnts) {
        struct pnt_normal *rpnt = (struct pnt_normal *)pnts->point;
        if (rpnt) {
@@ -1214,7 +1332,7 @@
 int
 _ged_nmg_obj(struct ged *gedp, int argc, const char **argv, const char 
*newname, struct _ged_facetize_opts *opts)
 {
-    int ret = GED_OK;
+    int ret = GED_FACETIZE_SUCCESS;
     struct model *nmg_model = NULL;
     struct rt_bot_internal *bot = NULL;
 
@@ -1223,7 +1341,7 @@
        if (opts->verbosity > 1) {
            bu_log("NMG(%s):  no resulting region, aborting\n", newname);
        }
-       ret = GED_ERROR;
+       ret = GED_FACETIZE_FAILURE;
        goto ged_nmg_obj_memfree;
     }
 
@@ -1233,7 +1351,7 @@
            if (opts->verbosity > 1) {
                bu_log("NMG(%s):  triangulation failed, aborting\n", newname);
            }
-           ret = GED_ERROR;
+           ret = GED_FACETIZE_FAILURE;
            goto ged_nmg_obj_memfree;
        }
     }
@@ -1248,7 +1366,7 @@
            if (opts->verbosity > 1) {
                bu_log("NMG(%s): conversion to BOT failed, aborting\n", 
newname);
            }
-           ret = GED_ERROR;
+           ret = GED_FACETIZE_FAILURE;
            goto ged_nmg_obj_memfree;
        }
 
@@ -1337,11 +1455,17 @@
                }
                flags = flags & ~(GED_FACETIZE_CONTINUATION);
            } else {
-               int is_valid = 1;
-               if (_ged_continuation_obj(&is_valid, gedp, argv[0], newname, 
opts) == GED_OK) {
+               struct _ged_facetize_report_info cinfo;
+               if (_ged_continuation_obj(&cinfo, gedp, argv[0], newname, opts) 
== GED_OK) {
                    done_trying = 1;
                    ret = GED_OK;
                } else {
+                   if (opts->verbosity) {
+                       struct bu_vls lmsg = BU_VLS_INIT_ZERO;
+                       _ged_facetize_failure_msg(&lmsg, cinfo.failure_mode, 
"Continuation Method", &cinfo);
+                       bu_log("%s", bu_vls_addr(&lmsg));
+                       bu_vls_free(&lmsg);
+                   }
                    flags = flags & ~(GED_FACETIZE_CONTINUATION);
                    continue;
                }
@@ -1434,21 +1558,108 @@
     return ret;
 }
 
-#define GED_FACETIZE_INVALID -2
-#define GED_FACETIZE_FAIL -1
-#define GED_NMGBOOL_SUCCESS 0
-#define GED_SPSR_SUCCESS 1
-#define GED_CONTINUATION_SUCCESS 2
+int
+_ged_methodcomb_add(struct ged *gedp, struct _ged_facetize_opts *opts, const 
char *objname, int method)
+{
+    int ret = GED_OK;
+    struct bu_vls method_cname = BU_VLS_INIT_ZERO;
+    if (!objname || method == GED_FACETIZE_NULL) return GED_ERROR;
 
+    if (method == GED_FACETIZE_NMGBOOL && !bu_vls_strlen(opts->nmg_comb)) {
+       bu_vls_sprintf(opts->nmg_comb, "%s_NMGBOOL-0", 
bu_vls_addr(opts->froot));
+       bu_vls_incr(opts->nmg_comb, NULL, NULL, &_db_uniq_test, (void *)gedp);
+    }
+    if (method == GED_FACETIZE_CONTINUATION && 
!bu_vls_strlen(opts->continuation_comb)) {
+       bu_vls_sprintf(opts->continuation_comb, "%s_CONTINUATION-0", 
bu_vls_addr(opts->froot));
+       bu_vls_incr(opts->continuation_comb, NULL, NULL, &_db_uniq_test, (void 
*)gedp);
+    }
+    if (method == GED_FACETIZE_SPSR && !bu_vls_strlen(opts->spsr_comb)) {
+       bu_vls_sprintf(opts->spsr_comb, "%s_SPSR-0", bu_vls_addr(opts->froot));
+       bu_vls_incr(opts->spsr_comb, NULL, NULL, &_db_uniq_test, (void *)gedp);
+    }
+
+    switch (method) {
+       case GED_FACETIZE_NMGBOOL:
+           bu_vls_sprintf(&method_cname, "%s", bu_vls_addr(opts->nmg_comb));
+           break;
+       case GED_FACETIZE_CONTINUATION:
+           bu_vls_sprintf(&method_cname, "%s", 
bu_vls_addr(opts->continuation_comb));
+           break;
+       case GED_FACETIZE_SPSR:
+           bu_vls_sprintf(&method_cname, "%s", bu_vls_addr(opts->spsr_comb));
+           break;
+       default:
+           bu_vls_free(&method_cname);
+           return GED_ERROR;
+           break;
+    }
+
+    ret =_ged_combadd2(gedp, bu_vls_addr(&method_cname), 1, (const char 
**)&objname, 0, DB_OP_UNION, 0, 0, NULL, 0);
+    bu_vls_free(&method_cname);
+    return ret;
+}
+
+void
+_ged_methodattr_set(struct ged *gedp, struct _ged_facetize_opts *opts, const 
char *rcname, int method, struct _ged_facetize_report_info *info)
+{
+    struct bu_vls anum = BU_VLS_INIT_ZERO;
+    const char *attrav[5];
+    attrav[0] = "attr";
+    attrav[1] = "set";
+    attrav[2] = rcname;
+
+    if (method == GED_FACETIZE_NMGBOOL) {
+       struct rt_tess_tol *tol = &(gedp->ged_wdbp->wdb_ttol);
+       attrav[3] = "nmg_abs";
+       bu_vls_sprintf(&anum, "%g", tol->abs);
+       attrav[4] = bu_vls_addr(&anum);
+       if (ged_attr(gedp, 5, (const char **)&attrav) != GED_OK && 
opts->verbosity) {
+           bu_log("Error adding attribute %s to comb %s", attrav[3], rcname);
+       }
+       attrav[3] = "nmg_rel";
+       bu_vls_sprintf(&anum, "%g", tol->rel);
+       attrav[4] = bu_vls_addr(&anum);
+       if (ged_attr(gedp, 5, (const char **)&attrav) != GED_OK && 
opts->verbosity) {
+           bu_log("Error adding attribute %s to comb %s", attrav[3], rcname);
+       }
+       attrav[3] = "nmg_norm";
+       bu_vls_sprintf(&anum, "%g", tol->norm);
+       attrav[4] = bu_vls_addr(&anum);
+       if (ged_attr(gedp, 5, (const char **)&attrav) != GED_OK && 
opts->verbosity) {
+           bu_log("Error adding attribute %s to comb %s", attrav[3], rcname);
+       }
+    }
+
+    if (info && method == GED_FACETIZE_CONTINUATION) {
+       attrav[3] = "continuation_feature_size";
+       bu_vls_sprintf(&anum, "%g", info->feature_size);
+       attrav[4] = bu_vls_addr(&anum);
+       if (ged_attr(gedp, 5, (const char **)&attrav) != GED_OK && 
opts->verbosity) {
+           bu_log("Error adding attribute %s to comb %s", attrav[3], rcname);
+       }
+       attrav[3] = "continuation_average_thickness";
+       bu_vls_sprintf(&anum, "%g", info->avg_thickness);
+       attrav[4] = bu_vls_addr(&anum);
+       if (ged_attr(gedp, 5, (const char **)&attrav) != GED_OK && 
opts->verbosity) {
+           bu_log("Error adding attribute %s to comb %s", attrav[3], rcname);
+       }
+    }
+
+    if (info && info->failure_mode == GED_FACETIZE_FAILURE_PNTGEN) {
+       attrav[3] = "EMPTY";
+       attrav[4] = "1";
+       if (ged_attr(gedp, 5, (const char **)&attrav) != GED_OK && 
opts->verbosity) {
+           bu_log("Error adding attribute %s to comb %s", attrav[3], rcname);
+       }
+    }
+}
+
 int
-_ged_facetize_region_obj(struct ged *gedp, const char *oname, const char 
*cname, const char *sname, struct _ged_facetize_opts *opts, int ocnt, int 
max_cnt)
+_ged_facetize_region_obj(struct ged *gedp, const char *oname, const char 
*cname, const char *sname, struct _ged_facetize_opts *opts, int ocnt, int 
max_cnt, int cmethod)
 {
-    struct bu_vls invalid_name = BU_VLS_INIT_ZERO;
-    int ret = GED_FACETIZE_FAIL;
+    int ret = GED_FACETIZE_FAILURE;
 
-    if (opts->method_flags & GED_FACETIZE_NMGBOOL) {
-       /* Return this unless we fail */
-       ret = GED_NMGBOOL_SUCCESS;
+    if (cmethod == GED_FACETIZE_NMGBOOL) {
 
        /* We're staring a new object, so we want to write out the header in the
         * log file the first time we get an NMG logging event.  (Re)set the 
flag
@@ -1461,90 +1672,73 @@
            bu_log("%s", bu_vls_addr(opts->nmg_log_header));
        }
 
-       if (_ged_nmg_obj(gedp, 1, (const char **)&oname, sname, opts) != 
GED_OK) {
-           ret = GED_FACETIZE_FAIL;
+       ret = _ged_nmg_obj(gedp, 1, (const char **)&oname, sname, opts);
+
+       if (ret != GED_FACETIZE_FAILURE) {
+           if (_ged_methodcomb_add(gedp, opts, sname, GED_FACETIZE_NMGBOOL) != 
GED_OK && opts->verbosity > 1) {
+               bu_log("Error adding %s to methodology combination\n", sname);
+           }
        }
+
+       /* Regardless of the outcome, record what settings were tried. */
+       _ged_methodattr_set(gedp, opts, cname, GED_FACETIZE_NMGBOOL, NULL);
+
+       return ret;
     }
 
-    if (ret < 0 && opts->method_flags & GED_FACETIZE_CONTINUATION) {
-       int is_valid = 0;
-       ret = GED_CONTINUATION_SUCCESS;
-       if (_ged_continuation_obj(&is_valid, gedp, oname, sname, opts) == 
GED_OK) {
-           /* Check the validity */
-           ret = (is_valid) ? GED_CONTINUATION_SUCCESS : GED_FACETIZE_INVALID;
-           if (ret == GED_FACETIZE_INVALID) {
-               bu_vls_sprintf(&invalid_name, "%s_CONTINUATION_INVALID-0", 
sname);
+    if (cmethod == GED_FACETIZE_CONTINUATION) {
+       struct _ged_facetize_report_info cinfo;
+
+       if (!opts->quiet) {
+           bu_log("Continuation Method: tessellating %s (%d of %d)\n", oname, 
ocnt, max_cnt);
+       }
+
+       ret = _ged_continuation_obj(&cinfo, gedp, oname, sname, opts);
+       if (ret == GED_FACETIZE_FAILURE) {
+           if (opts->verbosity) {
+               struct bu_vls lmsg = BU_VLS_INIT_ZERO;
+               _ged_facetize_failure_msg(&lmsg, cinfo.failure_mode, 
"Continuation Method", &cinfo);
+               bu_log("%s", bu_vls_addr(&lmsg));
+               bu_vls_free(&lmsg);
            }
        } else {
-           ret = GED_FACETIZE_FAIL;
+           if (_ged_methodcomb_add(gedp, opts, sname, 
GED_FACETIZE_CONTINUATION) != GED_OK && opts->verbosity > 1) {
+               bu_log("Error adding %s to methodology combination\n", sname);
+           }
        }
+
+       /* Regardless of the outcome, record what settings were tried. */
+       _ged_methodattr_set(gedp, opts, cname, GED_FACETIZE_CONTINUATION, 
&cinfo);
+
+       return ret;
     }
 
-    if (ret < 0 && opts->method_flags & GED_FACETIZE_SPSR) {
+    if (cmethod == GED_FACETIZE_SPSR) {
        int is_valid = 0;
-       ret = GED_SPSR_SUCCESS;
+       ret = GED_FACETIZE_SUCCESS;
        if (_ged_spsr_obj(&is_valid, gedp, oname, sname, opts) == GED_OK) {
            /* Check the validity */
-           ret = (is_valid) ? GED_SPSR_SUCCESS : GED_FACETIZE_INVALID;
-           if (ret == GED_FACETIZE_INVALID) {
-               bu_vls_sprintf(&invalid_name, "%s_SPSR_INVALID-0", sname);
-           }
+           ret = (is_valid) ? GED_FACETIZE_SUCCESS : GED_FACETIZE_FAILURE;
+           return ret;
        } else {
-           ret = GED_FACETIZE_FAIL;
+           return GED_FACETIZE_FAILURE;
        }
     }
 
-    if (ret >= 0) {
-       /* Success - remove the restart attributes */
-       const char *attrav[4];
-       attrav[0] = "attr";
-       attrav[1] = "rm";
-       attrav[2] = cname;
-       attrav[3] = "facetize_original_region";
-       if (ged_attr(gedp, 4, (const char **)&attrav) != GED_OK && 
opts->verbosity) {
-           bu_log("Error removing attribute \"facetize_original_region\" from 
comb %s", cname);
-       }
-       attrav[3] = "facetize_target_bot_name";
-       if (ged_attr(gedp, 4, (const char **)&attrav) != GED_OK && 
opts->verbosity) {
-           bu_log("Error removing attribute \"facetize_target_bot_name\" from 
comb %s", cname);
-       }
-    } else {
-       if (bu_vls_strlen(&invalid_name)) {
-           /* We ended up with an invalid object - rename to
-            * INVALID and update the name map.
-            * (Note: by this point in the logic we have created all the combs
-            * we need with the correct names, so we can stash the invalid name
-            * in the bu_avs.  If we ever want to return more than one invalid
-            * object per input region this won't scale, but for now it's
-            * simple. */
-           const char *mav[3];
-           mav[0] = "mv";
-           mav[1] = sname;
-           mav[2] = bu_vls_addr(&invalid_name);
-           if (ged_move(gedp, 3, (const char **)mav) != GED_OK && 
opts->verbosity) {
-               bu_log("Error: could not move failed SPSR shape %s to name 
%s\n", oname, bu_avs_get(opts->s_map, oname));
-           }
-           /* Now that we are done with sname (which was pointing to the
-            * opts->s_map entry) update the map */
-           bu_avs_add(opts->s_map, oname, bu_vls_addr(&invalid_name));
-       }
-    }
-
-    bu_vls_free(&invalid_name);
-    return ret;
+    return GED_FACETIZE_FAILURE;
 }
 
 int
 _ged_facetize_regions_resume(struct ged *gedp, int argc, const char **argv, 
struct _ged_facetize_opts *opts)
 {
+    int to_convert = 0;
+    int methods = opts->method_flags;
     unsigned int i = 0;
     int newobj_cnt = 0;
     int ret = GED_OK;
     struct bu_ptbl *ar = NULL;
+    struct bu_ptbl *ar2 = NULL;
     const char *resume_regions = "-attr facetize_original_region";
-    struct bu_ptbl spsr_succeeded = BU_PTBL_INIT_ZERO;
-    struct bu_ptbl spsr_failed = BU_PTBL_INIT_ZERO;
-    struct bu_ptbl facetize_failed = BU_PTBL_INIT_ZERO;
     struct directory **dpa = NULL;
     struct bu_attribute_value_set rnames;
     struct bu_attribute_value_set bnames;
@@ -1555,6 +1749,9 @@
     bu_avs_init_empty(&bnames);
     bu_avs_init_empty(&rnames);
 
+    /* Use the first object name for the root */
+    bu_vls_sprintf(opts->froot, "%s", argv[0]);
+
     /* Used the libged tolerances */
     opts->tol = &(gedp->ged_wdbp->wdb_ttol);
 
@@ -1578,70 +1775,92 @@
        /* No active regions (possible), nothing to do */
        ret = GED_OK;
        goto ged_facetize_regions_resume_memfree;
-    } else {
-       for (i = 0; i < BU_PTBL_LEN(ar); i++) {
-           struct directory *n = (struct directory *)BU_PTBL_GET(ar, i);
-           struct bu_attribute_value_set avs;
-           const char *rname;
-           const char *bname;
-           bu_avs_init_empty(&avs);
-           if (db5_get_attributes(gedp->ged_wdbp->dbip, &avs, n)) continue;
-           rname = bu_avs_get(&avs, "facetize_original_region");
-           bname = bu_avs_get(&avs, "facetize_target_bot_name");
-           if (!rname || !bname) {
-               bu_avs_free(&avs);
-               continue;
-           }
-           bu_avs_add(&bnames, n->d_namep, bname);
-           bu_avs_add(&rnames, n->d_namep, rname);
-           bu_avs_free(&avs);
-       }
     }
 
+    /* Only work on regions with conversion information */
+    BU_ALLOC(ar2, struct bu_ptbl);
+    bu_ptbl_init(ar2, 8, "second table");
     for (i = 0; i < BU_PTBL_LEN(ar); i++) {
        struct directory *n = (struct directory *)BU_PTBL_GET(ar, i);
-       const char *cname = n->d_namep;
-       const char *sname = bu_avs_get(&bnames, cname);
-       const char *oname = bu_avs_get(&rnames, cname);
+       struct bu_attribute_value_set avs;
+       const char *rname;
+       const char *bname;
+       bu_avs_init_empty(&avs);
+       if (db5_get_attributes(gedp->ged_wdbp->dbip, &avs, n)) continue;
+       rname = bu_avs_get(&avs, "facetize_original_region");
+       bname = bu_avs_get(&avs, "facetize_target_name");
+       if (!rname || !bname) {
+           bu_avs_free(&avs);
+           continue;
+       }
+       bu_avs_add(&bnames, n->d_namep, bname);
+       bu_avs_add(&rnames, n->d_namep, rname);
+       bu_ptbl_ins(ar2, (long *)n);
+       bu_avs_free(&avs);
+    }
 
-       int fret = _ged_facetize_region_obj(gedp, oname, cname, sname, opts, 
i+1, (int)BU_PTBL_LEN(ar));
-       if (fret < 0) {
-           bu_ptbl_ins(&facetize_failed, (long *)oname);
+    to_convert = BU_PTBL_LEN(ar2);
+    if (!to_convert) {
+       /* No regions with conversion information, nothing to do */
+       ret = GED_OK;
+       goto ged_facetize_regions_resume_memfree;
+    }
+
+    while (methods && BU_PTBL_LEN(ar2) > 0) {
+       struct bu_ptbl *tmp;
+       int cmethod = 0;
+       bu_ptbl_reset(ar);
+
+       if (!cmethod && (methods & GED_FACETIZE_NMGBOOL)) {
+           cmethod = GED_FACETIZE_NMGBOOL;
+           methods = methods & ~(GED_FACETIZE_NMGBOOL);
        }
-       if (fret == GED_FACETIZE_INVALID) {
-           bu_ptbl_ins(&spsr_failed, (long *)bu_avs_get(opts->s_map, oname));
+
+       if (!cmethod && (methods & GED_FACETIZE_CONTINUATION)) {
+           cmethod = GED_FACETIZE_CONTINUATION;
+           methods = methods & ~(GED_FACETIZE_CONTINUATION);
        }
-       if (fret == GED_SPSR_SUCCESS) {
-           bu_ptbl_ins(&spsr_succeeded, (long *)bu_avs_get(opts->s_map, 
oname));
+
+       if (!cmethod && (methods & GED_FACETIZE_SPSR)) {
+           cmethod = GED_FACETIZE_SPSR;
+           methods = methods & ~(GED_FACETIZE_SPSR);
        }
+
+       for (i = 0; i < BU_PTBL_LEN(ar2); i++) {
+           struct directory *n = (struct directory *)BU_PTBL_GET(ar, i);
+           const char *cname = n->d_namep;
+           const char *sname = bu_avs_get(&bnames, cname);
+           const char *oname = bu_avs_get(&rnames, cname);
+           struct directory *dp = db_lookup(dbip, sname, LOOKUP_QUIET);
+
+           if (dp == RT_DIR_NULL) {
+               if (_ged_facetize_region_obj(gedp, oname, cname, sname, opts, 
i+1, (int)BU_PTBL_LEN(ar), cmethod) == GED_FACETIZE_FAILURE) {
+                   bu_ptbl_ins(ar, (long *)n);
+               }
+           }
+       }
+
+       tmp = ar;
+       ar = ar2;
+       ar2 = tmp;
     }
 
-    /* For easier user inspection of what happened, make some high level 
debugging combs */
-    if (BU_PTBL_LEN(&facetize_failed) > 0) {
+    /* Stash the failures */
+    if (BU_PTBL_LEN(ar2) > 0) {
        /* Stash any failed regions into a top level comb for easy subsequent 
examination */
+       const char **avv = (const char **)bu_calloc(BU_PTBL_LEN(ar2)+1, 
sizeof(char *), "argv array");
        struct bu_vls failed_name = BU_VLS_INIT_ZERO;
        bu_vls_sprintf(&failed_name, "%s_FAILED-0", argv[0]);
        bu_vls_incr(&failed_name, NULL, NULL, &_db_uniq_test, (void *)gedp);
-       ret = _ged_combadd2(gedp, bu_vls_addr(&failed_name), 
(int)BU_PTBL_LEN(&facetize_failed), (const char **)facetize_failed.buffer, 0, 
DB_OP_UNION, 0, 0, NULL, 0);
+       for (i = 0; i < BU_PTBL_LEN(ar); i++) {
+           struct directory *n = (struct directory *)BU_PTBL_GET(ar2, i);
+           avv[i] = n->d_namep;
+       }
+       ret = _ged_combadd2(gedp, bu_vls_addr(&failed_name), 
(int)BU_PTBL_LEN(ar2), avv, 0, DB_OP_UNION, 0, 0, NULL, 0);
+       bu_vls_free(&failed_name);
+       bu_free(avv, "argv array");
     }
-    if (BU_PTBL_LEN(&spsr_succeeded) > 0) {
-       /* Put all of the spsr tessellations into their own top level comb for
-        * easy manual inspection */
-       struct bu_vls spsr_name = BU_VLS_INIT_ZERO;
-       bu_vls_sprintf(&spsr_name, "%s_SPSR-0", argv[0]);
-       bu_vls_incr(&spsr_name, NULL, NULL, &_db_uniq_test, (void *)gedp);
-       ret = _ged_combadd2(gedp, bu_vls_addr(&spsr_name), 
(int)BU_PTBL_LEN(&spsr_succeeded), (const char **)spsr_succeeded.buffer, 0, 
DB_OP_UNION, 0, 0, NULL, 0);
-    }
-    if (BU_PTBL_LEN(&spsr_failed) > 0) {
-       /* Put all of the spsr failed tessellations into their own top level 
comb for
-        * easy manual inspection */
-       struct bu_vls spsr_name = BU_VLS_INIT_ZERO;
-       bu_vls_sprintf(&spsr_name, "%s_SPSR_FAILED-0", argv[0]);
-       bu_vls_incr(&spsr_name, NULL, NULL, &_db_uniq_test, (void *)gedp);
-       ret = _ged_combadd2(gedp, bu_vls_addr(&spsr_name), 
(int)BU_PTBL_LEN(&spsr_failed), (const char **)spsr_failed.buffer, 0, 
DB_OP_UNION, 0, 0, NULL, 0);
-    }
 
-
 ged_facetize_regions_resume_memfree:
 
     /* Done changing stuff - update nref. */
@@ -1652,23 +1871,20 @@
     }
 
     /* Final report */
-    bu_vls_printf(gedp->ged_result_str, "Objects successfully converted: %d of 
%d\n", BU_PTBL_LEN(ar) - BU_PTBL_LEN(&facetize_failed), BU_PTBL_LEN(ar));
-    if (BU_PTBL_LEN(&spsr_succeeded)) {
-       bu_vls_printf(gedp->ged_result_str, "Objects converted with SPSR: 
%d\n", BU_PTBL_LEN(&spsr_succeeded));
-    }
-    if (BU_PTBL_LEN(&facetize_failed)) {
-       bu_vls_printf(gedp->ged_result_str, "WARNING: %d objects failed:\n", 
BU_PTBL_LEN(&facetize_failed));
-       for (i = 0; i < BU_PTBL_LEN(&facetize_failed); i++) {
-           bu_vls_printf(gedp->ged_result_str, "       %s\n", (const char 
*)BU_PTBL_GET(&facetize_failed, i));
+    bu_vls_printf(gedp->ged_result_str, "Objects successfully converted: %d of 
%d\n", to_convert - BU_PTBL_LEN(ar2), to_convert);
+    if (BU_PTBL_LEN(ar2)) {
+       bu_vls_printf(gedp->ged_result_str, "WARNING: %d objects failed:\n", 
BU_PTBL_LEN(ar2));
+       for (i = 0; i < BU_PTBL_LEN(ar2); i++) {
+           struct directory *n = (struct directory *)BU_PTBL_GET(ar2, i);
+           bu_vls_printf(gedp->ged_result_str, "       %s\n", n->d_namep);
        }
     }
 
     bu_avs_free(&bnames);
     bu_avs_free(&rnames);
-    bu_ptbl_free(&facetize_failed);
-    bu_ptbl_free(&spsr_succeeded);
-    bu_ptbl_free(&spsr_failed);
+    bu_ptbl_free(ar2);
     bu_ptbl_free(ar);
+    bu_free(ar2, "ar table");
     bu_free(ar, "ar table");
     bu_free(dpa, "free dpa");
 
@@ -1771,6 +1987,8 @@
 int
 _ged_facetize_regions(struct ged *gedp, int argc, const char **argv, struct 
_ged_facetize_opts *opts)
 {
+    int to_convert = 0;
+    int methods = opts->method_flags;
     char *newname = NULL;
     int newobj_cnt = 0;
     int ret = GED_OK;
@@ -1779,9 +1997,7 @@
     struct db_i *dbip = gedp->ged_wdbp->dbip;
     struct bu_ptbl *pc = NULL;
     struct bu_ptbl *ar = NULL;
-    struct bu_ptbl continuation_succeeded = BU_PTBL_INIT_ZERO;
-    struct bu_ptbl continuation_failed = BU_PTBL_INIT_ZERO;
-    struct bu_ptbl facetize_failed = BU_PTBL_INIT_ZERO;
+    struct bu_ptbl *ar2 = NULL;
 
     /* We need to copy combs above regions that are not themselves regions.
      * Also, facetize will need all "active" regions that will define shapes.
@@ -1806,6 +2022,14 @@
        argc--;
     }
 
+    if (!newname) {
+       bu_vls_sprintf(opts->froot, "%s", argv[0]);
+    } else {
+       /* Use the new name for the root */
+       bu_vls_sprintf(opts->froot, "%s", newname);
+    }
+
+
     /* Set up mapping names for the original toplevel object(s).  If we have
      * top level solids, deal with them now. */
     for (i = 0; i < (unsigned int)argc; i++) {
@@ -1949,11 +2173,12 @@
                attrav[3] = "facetize_original_region";
                attrav[4] = n->d_namep;
                if (ged_attr(gedp, 5, (const char **)&attrav) != GED_OK && 
opts->verbosity) {
-                   bu_log("Error adding %s to comb %s", ssname, rcname);
+                   bu_log("Error adding attribute facetize_original_region to 
comb %s", rcname);
                }
-               attrav[3] = "facetize_target_bot_name";
+               attrav[3] = "facetize_target_name";
                attrav[4] = ssname;
                if (ged_attr(gedp, 5, (const char **)&attrav) != GED_OK && 
opts->verbosity) {
+                   bu_log("Error adding attribute facetize_target_name to comb 
%s", rcname);
                    bu_log("Error adding %s to comb %s", ssname, rcname);
                }
            }
@@ -1966,50 +2191,65 @@
      * TODO - someday this should be done in parallel, but that's one deep
      * rabbit hole - for now, just try them in order and make sure we can
      * handle (non-crashing) failures to convert sanely. */
-    for (i = 0; i < BU_PTBL_LEN(ar); i++) {
-       struct directory *n = (struct directory *)BU_PTBL_GET(ar, i);
-       const char *oname = n->d_namep;
-       const char *cname = bu_avs_get(opts->c_map, oname);
-       const char *sname = bu_avs_get(opts->s_map, oname);
-       int fret = _ged_facetize_region_obj(gedp, oname, cname, sname, opts, 
i+1, (int)BU_PTBL_LEN(ar));
-       if (fret < 0) {
-           bu_ptbl_ins(&facetize_failed, (long *)oname);
+    BU_ALLOC(ar2, struct bu_ptbl);
+    bu_ptbl_init(ar2, 8, "second table");
+    to_convert = BU_PTBL_LEN(ar);
+ 
+    while (methods && BU_PTBL_LEN(ar) > 0) {
+       struct bu_ptbl *tmp;
+       int cmethod = 0;
+       bu_ptbl_reset(ar2);
+
+       if (!cmethod && (methods & GED_FACETIZE_NMGBOOL)) {
+           cmethod = GED_FACETIZE_NMGBOOL;
+           methods = methods & ~(GED_FACETIZE_NMGBOOL);
        }
-       if (fret == GED_FACETIZE_INVALID) {
-           bu_ptbl_ins(&continuation_failed, (long *)bu_avs_get(opts->s_map, 
oname));
+
+       if (!cmethod && (methods & GED_FACETIZE_CONTINUATION)) {
+           cmethod = GED_FACETIZE_CONTINUATION;
+           methods = methods & ~(GED_FACETIZE_CONTINUATION);
        }
-       if (fret == GED_CONTINUATION_SUCCESS) {
-           bu_ptbl_ins(&continuation_succeeded, (long 
*)bu_avs_get(opts->s_map, oname));
+
+       if (!cmethod && (methods & GED_FACETIZE_SPSR)) {
+           cmethod = GED_FACETIZE_SPSR;
+           methods = methods & ~(GED_FACETIZE_SPSR);
        }
+
+       for (i = 0; i < BU_PTBL_LEN(ar); i++) {
+           struct directory *n = (struct directory *)BU_PTBL_GET(ar, i);
+           const char *oname = n->d_namep;
+           const char *cname = bu_avs_get(opts->c_map, oname);
+           const char *sname = bu_avs_get(opts->s_map, oname);
+           struct directory *dp = db_lookup(dbip, sname, LOOKUP_QUIET);
+
+           if (dp == RT_DIR_NULL) {
+               if (_ged_facetize_region_obj(gedp, oname, cname, sname, opts, 
i+1, (int)BU_PTBL_LEN(ar), cmethod) == GED_FACETIZE_FAILURE) {
+                   bu_ptbl_ins(ar2, (long *)n);
+               }
+           }
+       }
+
+       tmp = ar;
+       ar = ar2;
+       ar2 = tmp;
+
     }
 
     /* For easier user inspection of what happened, make some high level 
debugging combs */
-    if (BU_PTBL_LEN(&facetize_failed) > 0) {
+    if (BU_PTBL_LEN(ar) > 0) {
        /* Stash any failed regions into a top level comb for easy subsequent 
examination */
+       const char **avv = (const char **)bu_calloc(BU_PTBL_LEN(ar)+1, 
sizeof(char *), "argv array");
        struct bu_vls failed_name = BU_VLS_INIT_ZERO;
        bu_vls_sprintf(&failed_name, "%s_FAILED-0", newname);
        bu_vls_incr(&failed_name, NULL, NULL, &_db_uniq_test, (void *)gedp);
-       ret = _ged_combadd2(gedp, bu_vls_addr(&failed_name), 
(int)BU_PTBL_LEN(&facetize_failed), (const char **)facetize_failed.buffer, 0, 
DB_OP_UNION, 0, 0, NULL, 0);
+       for (i = 0; i < BU_PTBL_LEN(ar); i++) {
+           struct directory *n = (struct directory *)BU_PTBL_GET(ar, i);
+           avv[i] = n->d_namep;
+       }
+       ret = _ged_combadd2(gedp, bu_vls_addr(&failed_name), 
(int)BU_PTBL_LEN(ar), avv, 0, DB_OP_UNION, 0, 0, NULL, 0);
        bu_vls_free(&failed_name);
+       bu_free(avv, "argv array");
     }
-    if (BU_PTBL_LEN(&continuation_succeeded) > 0) {
-       /* Put all of the continuation tessellations into their own top level 
comb for
-        * easy manual inspection */
-       struct bu_vls continuation_name = BU_VLS_INIT_ZERO;
-       bu_vls_sprintf(&continuation_name, "%s_CONTINUATION-0", newname);
-       bu_vls_incr(&continuation_name, NULL, NULL, &_db_uniq_test, (void 
*)gedp);
-       ret = _ged_combadd2(gedp, bu_vls_addr(&continuation_name), 
(int)BU_PTBL_LEN(&continuation_succeeded), (const char 
**)continuation_succeeded.buffer, 0, DB_OP_UNION, 0, 0, NULL, 0);
-       bu_vls_free(&continuation_name);
-    }
-    if (BU_PTBL_LEN(&continuation_failed) > 0) {
-       /* Put all of the continuation failed tessellations into their own top 
level comb for
-        * easy manual inspection */
-       struct bu_vls continuation_name = BU_VLS_INIT_ZERO;
-       bu_vls_sprintf(&continuation_name, "%s_CONTINUATION_FAILED-0", newname);
-       bu_vls_incr(&continuation_name, NULL, NULL, &_db_uniq_test, (void 
*)gedp);
-       ret = _ged_combadd2(gedp, bu_vls_addr(&continuation_name), 
(int)BU_PTBL_LEN(&continuation_failed), (const char 
**)continuation_failed.buffer, 0, DB_OP_UNION, 0, 0, NULL, 0);
-       bu_vls_free(&continuation_name);
-    }
 
     if (opts->in_place) {
        /* The "new" tree is actually the preservation of the old tree in this
@@ -2036,23 +2276,20 @@
     }
 
     /* Final report */
-    bu_vls_printf(gedp->ged_result_str, "Objects successfully converted: %d of 
%d\n", BU_PTBL_LEN(ar) - BU_PTBL_LEN(&facetize_failed), BU_PTBL_LEN(ar));
-    if (BU_PTBL_LEN(&continuation_succeeded)) {
-       bu_vls_printf(gedp->ged_result_str, "Objects converted with the 
Continuation Method: %d\n", BU_PTBL_LEN(&continuation_succeeded));
-    }
-    if (BU_PTBL_LEN(&facetize_failed)) {
-       bu_vls_printf(gedp->ged_result_str, "WARNING: %d objects failed:\n", 
BU_PTBL_LEN(&facetize_failed));
-       for (i = 0; i < BU_PTBL_LEN(&facetize_failed); i++) {
-           bu_vls_printf(gedp->ged_result_str, "       %s\n", (const char 
*)BU_PTBL_GET(&facetize_failed, i));
+    bu_vls_printf(gedp->ged_result_str, "Objects successfully converted: %d of 
%d\n", to_convert - BU_PTBL_LEN(ar), to_convert);
+    if (BU_PTBL_LEN(ar)) {
+       bu_vls_printf(gedp->ged_result_str, "WARNING: %d objects failed:\n", 
BU_PTBL_LEN(ar));
+       for (i = 0; i < BU_PTBL_LEN(ar); i++) {
+           struct directory *n = (struct directory *)BU_PTBL_GET(ar, i);
+           bu_vls_printf(gedp->ged_result_str, "       %s\n", n->d_namep);
        }
     }
 
     bu_ptbl_free(pc);
+    bu_ptbl_free(ar2);
     bu_ptbl_free(ar);
-    bu_ptbl_free(&facetize_failed);
-    bu_ptbl_free(&continuation_succeeded);
-    bu_ptbl_free(&continuation_failed);
     bu_free(pc, "pc table");
+    bu_free(ar2, "ar table");
     bu_free(ar, "ar table");
     bu_free(dpa, "dpa array");
     return ret;

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
BRL-CAD Source Commits mailing list
brlcad-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to