From 45f7d303989810f9bcedfd4a4fd6db49a5baba4e Mon Sep 17 00:00:00 2001 From: hgn Date: Thu, 14 Apr 2022 23:34:28 +0100 Subject: [PATCH] increase error checking --- __init__.py | 3 +- cxr/cxr.h | 88 ++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 72 insertions(+), 19 deletions(-) diff --git a/__init__.py b/__init__.py index c5fb285..246fe95 100644 --- a/__init__.py +++ b/__init__.py @@ -1354,7 +1354,8 @@ class CXR_PREVIEW_OPERATOR(bpy.types.Operator): "No-Candidate",\ "Internal-Fail",\ "Non-Coplanar",\ - "Non-Convex Polygon"]\ + "Non-Convex Polygon",\ + "Bad Result"]\ [err.value] if static.RUNNING: diff --git a/cxr/cxr.h b/cxr/cxr.h index 518d197..0af9b8c 100644 --- a/cxr/cxr.h +++ b/cxr/cxr.h @@ -278,7 +278,8 @@ enum cxr_soliderr k_soliderr_no_solids, k_soliderr_degenerate_implicit, k_soliderr_non_coplanar_vertices, - k_soliderr_non_convex_poly + k_soliderr_non_convex_poly, + k_soliderr_bad_result }; /* @@ -711,9 +712,15 @@ static int cxr_mesh_link_loops( cxr_mesh *mesh ) if( *edge == -1 ) { *edge = i; - break; + goto next; } } + + /* Overflowed edge mapping... Duplicated faces. */ + free( polygon_edge_map ); + return 0; + + next:; } } for( int i = 0; i < mesh->abpolys.count; i ++ ) @@ -1537,22 +1544,30 @@ static int cxr_build_implicit_geo( cxr_mesh *mesh, int new_polys, int start ) return 1; } -/* - * Convexer's main algorithm - * - * Return the best availible convex solid from mesh, and patch the existing mesh - * to fill the gap where the new mesh left it. - * - * Returns NULL if shape is already convex or empty. - * This function will not preserve edge data such as freestyle, sharp etc. - */ -static cxr_mesh *cxr_pull_best_solid( - cxr_mesh *mesh, - int preserve_more_edges, - enum cxr_soliderr *err ) +static int cxr_reflex_err( cxr_mesh *mesh ) { - *err = k_soliderr_none; + int error = 0; + int *reflex_check = cxr_mesh_reflex_edges( mesh ); + + v3f *temp = cxr_ab_ptr(mesh->p_abverts, 0); + for( int i=0; iabedges.count; i++ ) + { + if( reflex_check[i] ) + { + cxr_debug_line( temp[mesh->edges[i].i0], + temp[mesh->edges[i].i1], + colour_error ); + error ++; + } + } + + free( reflex_check ); + return error; +} + +static int cxr_non_manifold_err( cxr_mesh *mesh ) +{ if( !cxr_mesh_link_loops(mesh) ) { #ifdef CXR_DEBUG @@ -1572,10 +1587,34 @@ static cxr_mesh *cxr_pull_best_solid( } } #endif + return 1; + } + + return 0; +} + +/* + * Convexer's main algorithm + * + * Return the best availible convex solid from mesh, and patch the existing mesh + * to fill the gap where the new mesh left it. + * + * Returns NULL if shape is already convex or empty. + * This function will not preserve edge data such as freestyle, sharp etc. + */ +static cxr_mesh *cxr_pull_best_solid( + cxr_mesh *mesh, + int preserve_more_edges, + enum cxr_soliderr *err ) +{ + *err = k_soliderr_none; + + if( cxr_non_manifold_err( mesh ) ) + { *err = k_soliderr_non_manifold; return NULL; } - + int *edge_tagged = cxr_mesh_reflex_edges( mesh ); int *vertex_tagged = cxr_mesh_reflex_vertices( mesh ); @@ -1917,7 +1956,17 @@ static cxr_mesh *cxr_pull_best_solid( free(solid_buffer); free(candidates); free(best_manifold.loops); - + + /* + * Do final checks on the mesh to make sure we diddn't introduce any + * errors + */ + if( cxr_non_manifold_err( pullmesh ) || cxr_reflex_err( pullmesh ) ) + { + *err = k_soliderr_bad_result; + return NULL; + } + return pullmesh; } @@ -1925,6 +1974,9 @@ static cxr_mesh *cxr_pull_best_solid( free(candidates); free(best_manifold.loops); + if( cxr_non_manifold_err( mesh ) || cxr_reflex_err( mesh ) ) + *err = k_soliderr_bad_result; + return NULL; } -- 2.25.1