increase error checking
authorhgn <hgodden00@gmail.com>
Thu, 14 Apr 2022 22:34:28 +0000 (23:34 +0100)
committerhgn <hgodden00@gmail.com>
Thu, 14 Apr 2022 22:34:28 +0000 (23:34 +0100)
__init__.py
cxr/cxr.h

index c5fb285828b0e881ecb443448687940f9b5887e4..246fe95cd7463b608575d12e2b0abf76a5c47263 100644 (file)
@@ -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:
index 518d197695dc37ac8d5d9085a5201d315eec578a..0af9b8c780fa68fd0b72755e5223b9ca7710c192 100644 (file)
--- 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; i<mesh->abedges.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;
 }