/* * Called from db_walk_tree(). * * This routine must be prepared to run in parallel. */ union tree *do_region_end(struct db_tree_state *tsp, const struct db_full_path *pathp, union tree *curtree, void *UNUSED(client_data)) { union tree *ret_tree; struct bu_list vhead; struct nmgregion *r; RT_CK_FULL_PATH(pathp); RT_CK_TREE(curtree); RT_CK_TESS_TOL(tsp->ts_ttol); BN_CK_TOL(tsp->ts_tol); NMG_CK_MODEL(*tsp->ts_m); BU_LIST_INIT(&vhead); { char *sofar = db_path_to_string(pathp); bu_log("\ndo_region_end(%d %d%%) %s\n", regions_tried, regions_tried>0 ? (regions_converted * 100) / regions_tried : 0, sofar); bu_free(sofar, "path string"); } if (curtree->tr_op == OP_NOP) return curtree; regions_tried++; if (verbose) bu_log("Attempting to process region %s\n", db_path_to_string(pathp)); ret_tree= process_boolean(curtree, tsp, pathp); if (ret_tree) r = ret_tree->tr_d.td_r; else { if (verbose) bu_log("\tNothing left of this region after Boolean evaluation\n"); regions_written++; /* don't count as a failure */ r = (struct nmgregion *)NULL; } regions_converted++; if (r != (struct nmgregion *)NULL) { struct shell *s; int empty_region=0; int empty_model=0; /* Kill cracks */ s = BU_LIST_FIRST(shell, &r->s_hd); while (BU_LIST_NOT_HEAD(&s->l, &r->s_hd)) { struct shell *next_s; next_s = BU_LIST_PNEXT(shell, &s->l); if (nmg_kill_cracks(s)) { if (nmg_ks(s)) { empty_region = 1; break; } } s = next_s; } /* kill zero length edgeuses */ if (!empty_region) { empty_model = nmg_kill_zero_length_edgeuses(*tsp->ts_m); } if (!empty_region && !empty_model) { process_triangulation(r, pathp, tsp); regions_written++; } if (!empty_model) nmg_kr(r); } /* * Dispose of original tree, so that all associated dynamic * memory is released now, not at the end of all regions. * A return of TREE_NULL from this routine signals an error, * and there is no point to adding _another_ message to our output, * so we need to cons up an OP_NOP node to return. */ db_free_tree(curtree, &rt_uniresource); /* Does an nmg_kr() */ BU_ALLOC(curtree, union tree); RT_TREE_INIT(curtree); curtree->tr_op = OP_NOP; return curtree; }
/** * This routine must be prepared to run in parallel. */ static union tree * draw_nmg_region_end(struct db_tree_state *tsp, const struct db_full_path *pathp, union tree *curtree, void *client_data) { struct nmgregion *r; struct bu_list vhead; int failed; struct _ged_client_data *dgcdp = (struct _ged_client_data *)client_data; RT_CK_TESS_TOL(tsp->ts_ttol); BN_CK_TOL(tsp->ts_tol); NMG_CK_MODEL(*tsp->ts_m); RT_CK_RESOURCE(tsp->ts_resp); BU_LIST_INIT(&vhead); if (RT_G_DEBUG&DEBUG_TREEWALK) { char *sofar = db_path_to_string(pathp); bu_vls_printf(dgcdp->gedp->ged_result_str, "nmg_region_end() path='%s'\n", sofar); bu_free((void *)sofar, "path string"); } else { char *sofar = db_path_to_string(pathp); bu_vls_printf(dgcdp->gedp->ged_result_str, "%s:\n", sofar); bu_free((void *)sofar, "path string"); } if (curtree->tr_op == OP_NOP) return curtree; failed = 1; if (!dgcdp->draw_nmg_only) { failed = process_boolean(curtree, tsp, pathp, dgcdp); if (failed) { db_free_tree(curtree, tsp->ts_resp); return (union tree *)NULL; } } else if (curtree->tr_op != OP_NMG_TESS) { bu_vls_printf(dgcdp->gedp->ged_result_str, "Cannot use '-d' option when Boolean evaluation is required\n"); db_free_tree(curtree, tsp->ts_resp); return (union tree *)NULL; } r = curtree->tr_d.td_r; NMG_CK_REGION(r); if (dgcdp->do_not_draw_nmg_solids_during_debugging && r) { db_free_tree(curtree, tsp->ts_resp); return (union tree *)NULL; } if (dgcdp->nmg_triangulate) { failed = process_triangulation(tsp, pathp, dgcdp); if (failed) { db_free_tree(curtree, tsp->ts_resp); return (union tree *)NULL; } } if (r != 0) { int style; /* Convert NMG to vlist */ NMG_CK_REGION(r); if (dgcdp->draw_wireframes) { /* Draw in vector form */ style = NMG_VLIST_STYLE_VECTOR; } else { /* Default -- draw polygons */ style = NMG_VLIST_STYLE_POLYGON; } if (dgcdp->draw_normals) { style |= NMG_VLIST_STYLE_VISUALIZE_NORMALS; } if (dgcdp->shade_per_vertex_normals) { style |= NMG_VLIST_STYLE_USE_VU_NORMALS; } if (dgcdp->draw_no_surfaces) { style |= NMG_VLIST_STYLE_NO_SURFACES; } nmg_r_to_vlist(&vhead, r, style); _ged_drawH_part2(0, &vhead, pathp, tsp, dgcdp); if (dgcdp->draw_edge_uses) { nmg_vlblock_r(dgcdp->draw_edge_uses_vbp, r, 1); } /* NMG region is no longer necessary, only vlist remains */ db_free_tree(curtree, tsp->ts_resp); return (union tree *)NULL; } /* Return tree -- it needs to be freed (by caller) */ return curtree; }