X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=cxr%2Fcxr.h;fp=cxr%2Fcxr.h;h=bb904c4d00ba8ce0522935f03787d0145e11c4e8;hb=e6de1b2b1d8456cdebd75ccc7640bc0a5740a3b0;hp=5a4542af6d1a3f4055233c6611630e13b771e10b;hpb=2937c186209f5ff766cacc9f17a118744ede7b7a;p=convexer.git diff --git a/cxr/cxr.h b/cxr/cxr.h index 5a4542a..bb904c4 100644 --- a/cxr/cxr.h +++ b/cxr/cxr.h @@ -107,7 +107,7 @@ typedef struct cxr_tri_mesh cxr_tri_mesh; /* Main convexer algorithms */ /* Convex decomp from mesh */ -CXR_API cxr_world *cxr_decompose( cxr_static_mesh *src ); +CXR_API cxr_world *cxr_decompose( cxr_static_mesh *src, i32 *perrcode ); CXR_API void cxr_free_world( cxr_world *world ); CXR_API cxr_tri_mesh *cxr_world_preview( cxr_world *world ); CXR_API void cxr_free_tri_mesh( cxr_tri_mesh *mesh ); @@ -276,7 +276,9 @@ enum cxr_soliderr k_soliderr_non_manifold, k_soliderr_bad_manifold, k_soliderr_no_solids, - k_soliderr_degenerate_implicit + k_soliderr_degenerate_implicit, + k_soliderr_non_coplanar_vertices, + k_soliderr_non_convex_poly }; /* @@ -1556,6 +1558,19 @@ static cxr_mesh *cxr_pull_best_solid( #ifdef CXR_DEBUG cxr_log( "non-manifold edges are in the mesh: " "implicit internal geometry does not have full support\n" ); + + v3f *verts = cxr_ab_ptr( mesh->p_abverts, 0 ); + + for( int i=0; iabloops.count; i++ ) + { + cxr_loop *lp = &mesh->loops[i]; + + if( lp->poly_left == -1 || lp->poly_right == -1 ) + { + cxr_edge *edge = &mesh->edges[lp->edge_index]; + cxr_debug_line( verts[edge->i0], verts[edge->i1], colour_error ); + } + } #endif *err = k_soliderr_non_manifold; return NULL; @@ -1948,6 +1963,40 @@ static cxr_mesh *cxr_to_internal_format( return mesh; } +static int cxr_poly_convex( cxr_mesh *mesh, cxr_polygon *poly ) +{ + v3f *verts = cxr_ab_ptr( mesh->p_abverts, 0 ); + + for( int i=0; iloop_total; i++ ) + { + int li0 = poly->loop_start + i, + li1 = poly->loop_start + cxr_range( i+1, poly->loop_total ), + li2 = poly->loop_start + cxr_range( i+2, poly->loop_total ); + int i0 = mesh->loops[li0].index, + i1 = mesh->loops[li1].index, + i2 = mesh->loops[li2].index; + + v3f v0, v1, c; + + v3_sub( verts[i1], verts[i0], v0 ); + v3_sub( verts[i2], verts[i1], v1 ); + + v3_cross( v0, v1, c ); + if( v3_dot( c, poly->normal ) <= 0.0 ) + { +#if CXR_DEBUG + cxr_debug_line( verts[i0], verts[i1], colour_error ); + cxr_debug_box( verts[i1], 0.1, colour_error ); + cxr_debug_line( verts[i1], verts[i2], colour_error ); + cxr_debug_line( verts[i1], poly->center, colour_error ); +#endif + return 0; + } + } + + return 1; +} + static int cxr_solid_checkerr( cxr_mesh *mesh ) { v3f *verts = cxr_ab_ptr( mesh->p_abverts, 0 ); @@ -2113,8 +2162,9 @@ CXR_API void cxr_free_tri_mesh( cxr_tri_mesh *mesh ) free( mesh ); } -CXR_API cxr_world *cxr_decompose( cxr_static_mesh *src ) +CXR_API cxr_world *cxr_decompose( cxr_static_mesh *src, i32 *perrcode ) { + u32 error = 0x00; cxr_world *world = malloc( sizeof(*world) ); /* Copy data to internal formats */ @@ -2164,12 +2214,20 @@ CXR_API cxr_world *cxr_decompose( cxr_static_mesh *src ) if( edge->freestyle ) goto displacement; } + + if( !cxr_poly_convex( pinf->pmesh, poly ) ) + { + pinf->invalid = 1; + invalid_count ++; + error = k_soliderr_non_convex_poly; + } } if( cxr_solid_checkerr( pinf->pmesh ) ) { pinf->invalid = 1; invalid_count ++; + error = k_soliderr_non_coplanar_vertices; } continue; @@ -2182,7 +2240,6 @@ CXR_API cxr_world *cxr_decompose( cxr_static_mesh *src ) * Main convex decomp algorithm */ int sources_count = world->absolids.count; - u32 error = 0x00; if( invalid_count ) goto decomp_failed; @@ -2228,6 +2285,10 @@ CXR_API cxr_world *cxr_decompose( cxr_static_mesh *src ) decomp_failed: cxr_log( "Error %d\n", error ); cxr_free_world( world ); + + if( perrcode ) + *perrcode = error; + return NULL; }