From e09d3691cb55505c81624d93df7713dbbaafaa54 Mon Sep 17 00:00:00 2001 From: hgn Date: Sun, 17 Apr 2022 10:35:35 +0100 Subject: [PATCH] fixes some invalid solids --- __init__.py | 4 ++- cxr/cxr.h | 72 +++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 68 insertions(+), 8 deletions(-) diff --git a/__init__.py b/__init__.py index f874746..763e6e3 100644 --- a/__init__.py +++ b/__init__.py @@ -216,7 +216,8 @@ libcxr = None class cxr_edge(Structure): _fields_ = [("i0",c_int32), ("i1",c_int32), - ("freestyle",c_int32)] + ("freestyle",c_int32), + ("sharp",c_int32)] class cxr_static_loop(Structure): _fields_ = [("index",c_int32), @@ -327,6 +328,7 @@ def mesh_cxr_format(obj): edge_data[i].i0 = edge.vertices[0] edge_data[i].i1 = edge.vertices[1] edge_data[i].freestyle = edge.use_freestyle_mark + edge_data[i].sharp = edge.use_edge_sharp material_data = (cxr_material*len(obj.material_slots))() diff --git a/cxr/cxr.h b/cxr/cxr.h index 0af9b8c..9f11096 100644 --- a/cxr/cxr.h +++ b/cxr/cxr.h @@ -146,7 +146,7 @@ struct cxr_static_mesh struct cxr_edge { i32 i0, i1; - i32 freestyle; + i32 freestyle, sharp; } *edges; @@ -517,10 +517,11 @@ CXR_API void cxr_write_test_data( cxr_static_mesh *src ) fprintf( fp, "cxr_edge test_edges[] = {\n" ); for( int i=0; iedge_count; i++ ) { - fprintf( fp, " {%d, %d, %d},\n", + fprintf( fp, " {%d, %d, %d, %d},\n", src->edges[i].i0, src->edges[i].i1, - src->edges[i].freestyle + src->edges[i].freestyle, + src->edges[i].sharp ); } fprintf( fp, "};\n" ); @@ -622,10 +623,12 @@ static void cxr_mesh_clean_edges( cxr_mesh *mesh ) { cxr_edge *orig_edge = &mesh->edges[ orig_edge_id ]; edge.freestyle = orig_edge->freestyle; + edge.sharp = orig_edge->sharp; } else { edge.freestyle = 0; + edge.sharp = 0; } cxr_ab_push( &new_edges, &edge ); @@ -1008,7 +1011,7 @@ static int *cxr_mesh_reflex_edges( cxr_mesh *mesh ) edge_tagged[lp->edge_index] = 0; cxr_polygon *polya = &mesh->polys[ lp->poly_left ], - *polyb = &mesh->polys[ lp->poly_right ]; + *polyb = &mesh->polys[ lp->poly_right ]; v4f planeb; normal_to_plane(polyb->normal, polyb->center, planeb); @@ -1327,16 +1330,70 @@ static void cxr_link_manifold( struct temp_manifold *manifold ){ cxr_loop **edge_list = malloc( sizeof(*edge_list) * solid->edge_count ); + int *temp_solid = malloc( solid->count *sizeof(int) ); + int temp_solid_len = 0; int init_reverse = 0; int unique_edge_count = 0; + int discard_splits = 1; + + /* Try remove splitting faces first */ + { + for( int j=0; jcount; j++ ) + { + cxr_polygon *poly = &mesh->polys[ solid_buffer[solid->start+j] ]; + int interior_count = 0; + + for( int k=0; kloop_total; k++ ) + { + cxr_loop *loop = &mesh->loops[ poly->loop_start+k ]; + + for( int l=0; lcount; l++ ) + if( loop->poly_right == solid_buffer[solid->start+l] ) + { + interior_count ++; + goto next; + } + + next:; + } + + if( interior_count < poly->loop_total-1 ) + continue; + + temp_solid[ temp_solid_len ++ ] = solid_buffer[solid->start+j]; + } + + if( temp_solid_len < 3 ) + { + /* Revert back to normal */ + free( temp_solid ); + + temp_solid = &solid_buffer[ solid->start ]; + temp_solid_len = solid->count; + discard_splits = 0; + } + else + { + /* Overwrite original solid */ + for( int j=0; jstart+j ] = temp_solid[ j ]; - /* Gather list of unique edges */ + solid->count = temp_solid_len; + } + + if( discard_splits ) + free( temp_solid ); + } for( int j=0; jcount; j++ ) { cxr_polygon *poly = &mesh->polys[ solid_buffer[solid->start+j] ]; + /* when discarding, if a face has only one loop that points outwards, + * we keep it */ + + for( int k=0; kloop_total; k++ ) { cxr_loop *loop = &mesh->loops[ poly->loop_start+k ]; @@ -1579,10 +1636,11 @@ static int cxr_non_manifold_err( cxr_mesh *mesh ) for( int i=0; iabloops.count; i++ ) { cxr_loop *lp = &mesh->loops[i]; + cxr_edge *edge = &mesh->edges[lp->edge_index]; + cxr_debug_line( verts[edge->i0], verts[edge->i1], colours_random[1] ); 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 ); } } @@ -1728,7 +1786,7 @@ static cxr_mesh *cxr_pull_best_solid( struct temp_manifold manifold; cxr_link_manifold( mesh, solid, solid_buffer, &manifold); - + if( manifold.status == k_manifold_err ) { *err = k_soliderr_bad_manifold; -- 2.25.1