X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=cxr%2Fcxr.h;fp=cxr%2Fcxr.h;h=0af9b8c780fa68fd0b72755e5223b9ca7710c192;hb=45f7d303989810f9bcedfd4a4fd6db49a5baba4e;hp=518d197695dc37ac8d5d9085a5201d315eec578a;hpb=5ed7781eb73157f2de21f848a828b321637926b6;p=convexer.git 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; }