From 57d45d2cbb91ecf55e83fc73a0d54853e741d376 Mon Sep 17 00:00:00 2001 From: Clifford Yapp <238416+starseeker@users.noreply.github.com> Date: Wed, 6 Dec 2023 21:08:27 -0500 Subject: [PATCH] Triggering it this time, but CM still not working in new setup yet - decimation failing. --- .../facetize/tessellate/continuation.cpp | 183 +++++++++--------- src/libged/facetize/tessellate/sample.cpp | 3 + src/libged/facetize/tri_booleval.cpp | 2 + 3 files changed, 100 insertions(+), 88 deletions(-) diff --git a/src/libged/facetize/tessellate/continuation.cpp b/src/libged/facetize/tessellate/continuation.cpp index fec7e434c9d..6dc49780e1c 100644 --- a/src/libged/facetize/tessellate/continuation.cpp +++ b/src/libged/facetize/tessellate/continuation.cpp @@ -58,22 +58,25 @@ _bbox_vol(point_t b_min, point_t b_max) return bbox_vol; } -int -continuation_mesh(struct rt_bot_internal **obot, struct db_i *dbip, const char *objname, struct tess_opts *s, point_t seed) +void free_bot_internal(struct rt_bot_internal *bot) { + if (!bot) + return; - int first_run = 1; - int fatal_error_cnt = 0; - int face_cnt = 0; - double successful_feature_size = 0.0; - unsigned int successful_bot_count = 0; - int decimation_succeeded = 0; - struct rt_bot_internal *bot = NULL; - int polygonize_failure = 0; - struct analyze_polygonize_params params = ANALYZE_POLYGONIZE_PARAMS_DEFAULT; - double feature_size = s->feature_size; + if (bot->faces) + bu_free(bot->faces, "faces"); + + if (bot->vertices) + bu_free(bot->vertices, "vertices"); + + BU_PUT(bot, struct rt_bot_internal); +} +int +bot_gen(struct rt_bot_internal **obot, fastf_t feature_size, point_t seed, const char *objname, struct db_i *dbip, struct analyze_polygonize_params *params) +{ /* Build the BoT */ + struct rt_bot_internal *bot; BU_GET(bot, struct rt_bot_internal); bot->magic = RT_BOT_INTERNAL_MAGIC; bot->mode = RT_BOT_SOLID; @@ -82,6 +85,38 @@ continuation_mesh(struct rt_bot_internal **obot, struct db_i *dbip, const char * bot->face_mode = (struct bu_bitv *)NULL; bot->faces = NULL; bot->vertices = NULL; + int ret = analyze_polygonize(&(bot->faces), (int *)&(bot->num_faces), + (point_t **)&(bot->vertices), + (int *)&(bot->num_vertices), + feature_size, seed, objname, dbip, params); + + if (ret == 3) + bu_log("CM: Too little available memory to continue, aborting\n"); + + if (ret == 2) + bu_log("CM: timed out after %d seconds with size %g\n", params->max_time, feature_size); + + if (!ret) { + *obot = bot; + } else { + free_bot_internal(bot); + } + return ret; +} + +int +continuation_mesh(struct rt_bot_internal **obot, struct db_i *dbip, const char *objname, struct tess_opts *s, point_t seed) +{ + + int first_run = 1; + int fatal_error_cnt = 0; + double successful_feature_size = 0.0; + int decimation_succeeded = 0; + struct rt_bot_internal *bot = NULL; + struct rt_bot_internal *dbot = NULL; + int pret = -1; + struct analyze_polygonize_params params = ANALYZE_POLYGONIZE_PARAMS_DEFAULT; + double feature_size = s->feature_size; /* Run the polygonize routine. Because it is quite simple to accidentally * specify inputs that will take huge amounts of time to run, we will @@ -95,81 +130,56 @@ continuation_mesh(struct rt_bot_internal **obot, struct db_i *dbip, const char * params.verbosity = 1; params.minimum_free_mem = FACETIZE_MEMORY_THRESHOLD; - while (!polygonize_failure && (feature_size > 0.9*s->target_feature_size || face_cnt < 1000) && fatal_error_cnt < 8) { + while (feature_size > 0.9*s->target_feature_size) { double timestamp = bu_gettime(); - int delta; - fastf_t *verts = bot->vertices; - int *faces = bot->faces; - int num_faces = bot->num_faces; - int num_verts = bot->num_vertices; - bot->vertices = NULL; - bot->faces = NULL; - polygonize_failure = analyze_polygonize(&(bot->faces), (int *)&(bot->num_faces), - (point_t **)&(bot->vertices), - (int *)&(bot->num_vertices), - feature_size, seed, objname, dbip, ¶ms); - delta = (int)((bu_gettime() - timestamp)/1e6); - if (polygonize_failure || bot->num_faces < successful_bot_count || delta < 2) { - if (polygonize_failure == 3) { - bu_log("CM: Too little available memory to continue, aborting\n"); - if (bot->vertices) bu_free(bot->vertices, "verts"); - if (bot->faces) bu_free(bot->faces, "verts"); - BU_PUT(bot, struct rt_bot_internal *); - return BRLCAD_ERROR; - } - if (polygonize_failure == 2) { - bu_log("CM: timed out after %d seconds with size %g\n", s->max_time, feature_size); - /* If we still haven't had a successful run, back the feature size out and try again */ - if (first_run) { - polygonize_failure = 0; - feature_size = feature_size * 5; - fatal_error_cnt++; - continue; + struct rt_bot_internal *candidate = NULL; + pret = bot_gen(&candidate, feature_size, seed, objname, dbip, ¶ms); + fastf_t delta = (int)((bu_gettime() - timestamp)/1e6); + if (s->max_time > 0 && delta > s->max_time) + break; + + if (!pret && candidate->num_faces) { + // Success - check output + if (!bot) { + bot = candidate; + successful_feature_size = feature_size; + } else { + if (bot->num_faces == candidate->num_faces) { + // Stable answer - breaking out of loop + free_bot_internal(candidate); + break; } - } - bot->faces = faces; - bot->vertices = verts; - bot->num_vertices = num_verts; - bot->num_faces = num_faces; - if (polygonize_failure != 2 && feature_size <= 0) { - /* Something about the previous size didn't work - nudge the feature size and try again - * unless we've had multiple fatal errors. */ - polygonize_failure = 0; - bu_log("CM: error at size %g\n", feature_size); - /* 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)); - bu_log("CM: retrying with size %g\n", feature_size); - fatal_error_cnt++; - continue; - } - feature_size = successful_feature_size; - if (bot->faces) { - if (feature_size <= 0) { - bu_log("CM: unable to polygonize at target size (%g), using last successful BoT with %d faces, feature size %g\n", s->target_feature_size, (int)bot->num_faces, successful_feature_size); + if (bot->num_faces < candidate->num_faces) { + free_bot_internal(bot); + bot = candidate; + successful_feature_size = feature_size; } else { - bu_log("CM: successfully created %d faces, feature size %g\n", (int)bot->num_faces, successful_feature_size); + // Lost faces compared to prior output - rejecting + free_bot_internal(candidate); } } - } else { - if (verts) bu_free(verts, "old verts"); - if (faces) bu_free(faces, "old faces"); - /* if we have had a fatal error in the past, reset on subsequent success */ - fatal_error_cnt = 0; - successful_feature_size = feature_size; - bu_log("CM: completed 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; - successful_bot_count = bot->num_faces; } + + if (pret) { + fatal_error_cnt++; + if (first_run) { + pret = 0; + feature_size = feature_size * 5; + } + } + first_run = 0; + if (pret == 2 || pret == 3) + break; + + /* Nudge the feature size and try again */ + pret = 0; + feature_size = feature_size * ((!first_run) ? 0.95 : ((fatal_error_cnt) ? 0.5 : 0.1)); + bu_log("CM: retrying with size %g\n", feature_size); } - if (bot->num_faces && feature_size < s->target_feature_size) { - bu_log("CM: successfully polygonized BoT with %d faces at feature size %g\n", (int)bot->num_faces, feature_size); + if (bot && bot->num_faces) { + bu_log("CM: successfully polygonized BoT with %d faces at feature size %g\n", (int)bot->num_faces, successful_feature_size); } if (!bot->faces) { @@ -187,21 +197,18 @@ continuation_mesh(struct rt_bot_internal **obot, struct db_i *dbip, const char * bu_log("CM: decimating with feature size %g\n", d_feature_size); - bot = _tess_facetize_decimate(bot, d_feature_size); + dbot = _tess_facetize_decimate(bot, d_feature_size); - if (bot == *obot) { - if (bot->vertices) bu_free(bot->vertices, "verts"); - if (bot->faces) bu_free(bot->faces, "verts"); - BU_PUT(bot, struct rt_bot_internal *); + if (bot == dbot || !dbot->num_vertices || !dbot->num_faces) { + bu_log("decimation failed\n"); return BRLCAD_ERROR; } - // TODO - double check that we're freeing memory here - did _tess_facetize_decimate handle it? - if (bot != *obot) { - decimation_succeeded = 1; - } + + bot = dbot; + decimation_succeeded = 1; } - /* Get the volume of the bounding box of the BoT */ + /* Get the volume of the bounding box of the decimated BoT */ point_t b_min, b_max; VSETALL(b_min, INFINITY); VSETALL(b_max, -INFINITY); diff --git a/src/libged/facetize/tessellate/sample.cpp b/src/libged/facetize/tessellate/sample.cpp index 12a89960b02..ee8bfea4641 100644 --- a/src/libged/facetize/tessellate/sample.cpp +++ b/src/libged/facetize/tessellate/sample.cpp @@ -163,6 +163,9 @@ _tess_pnts_sample(const char *oname, struct db_i *dbip, struct tess_opts *s) if (!(s->feature_size > 0)) { s->feature_size = 2*avg_thickness; } + if (!(s->target_feature_size > 0)) { + s->target_feature_size = 2*avg_thickness; + } return pnts; } diff --git a/src/libged/facetize/tri_booleval.cpp b/src/libged/facetize/tri_booleval.cpp index 7689730f620..39722e43657 100644 --- a/src/libged/facetize/tri_booleval.cpp +++ b/src/libged/facetize/tri_booleval.cpp @@ -408,6 +408,8 @@ tess_run(const char **tess_cmd, int tess_cmd_cnt, fastf_t max_time) bu_file_delete(wfilebak.c_str()); + bu_log("result: %d\n", w_rc); + return (timeout || w_rc) ? 1 : 0; }