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
};
/*
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 ++ )
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
}
}
#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 );
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;
}
free(candidates);
free(best_manifold.loops);
+ if( cxr_non_manifold_err( mesh ) || cxr_reflex_err( mesh ) )
+ *err = k_soliderr_bad_result;
+
return NULL;
}