fixes some invalid solids
authorhgn <hgodden00@gmail.com>
Sun, 17 Apr 2022 09:35:35 +0000 (10:35 +0100)
committerhgn <hgodden00@gmail.com>
Sun, 17 Apr 2022 09:35:35 +0000 (10:35 +0100)
__init__.py
cxr/cxr.h

index f8747467157eb627bba10d62dffc6d63fcc32a66..763e6e3479032d2985a09a6c571b02c4501143b5 100644 (file)
@@ -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))()
 
index 0af9b8c780fa68fd0b72755e5223b9ca7710c192..9f11096925ab8b105784ec411a5ced306951b39b 100644 (file)
--- 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; i<src->edge_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; j<solid->count; j++ )
+      {
+         cxr_polygon *poly = &mesh->polys[ solid_buffer[solid->start+j] ];
+         int interior_count = 0;
+
+         for( int k=0; k<poly->loop_total; k++ )
+         {
+            cxr_loop *loop = &mesh->loops[ poly->loop_start+k ];
+
+            for( int l=0; l<solid->count; 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; j<temp_solid_len; j++ )
+            solid_buffer[ solid->start+j ] = temp_solid[ j ];
 
-   /* Gather list of unique edges */
+         solid->count = temp_solid_len;
+      }
+
+      if( discard_splits )
+         free( temp_solid );
+   }
 
    for( int j=0; j<solid->count; 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; k<poly->loop_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; i<mesh->abloops.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;