Changeset View
Changeset View
Standalone View
Standalone View
source/blender/modifiers/intern/MOD_solidify_nonmanifold.c
| Show First 20 Lines • Show All 237 Lines • ▼ Show 20 Lines | for (uint i = 0; i < numPolys; i++, mp++) { | ||||
| .face = mp, .index = i, .reversed = false, .link_edges = link_edges}; | .face = mp, .index = i, .reversed = false, .link_edges = link_edges}; | ||||
| link_edges = MEM_calloc_arrayN( | link_edges = MEM_calloc_arrayN( | ||||
| (uint)mp->totloop, sizeof(*link_edges), "NewFaceRef::link_edges in solidify"); | (uint)mp->totloop, sizeof(*link_edges), "NewFaceRef::link_edges in solidify"); | ||||
| face_sides_arr[i * 2 + 1] = (NewFaceRef){ | face_sides_arr[i * 2 + 1] = (NewFaceRef){ | ||||
| .face = mp, .index = i, .reversed = true, .link_edges = link_edges}; | .face = mp, .index = i, .reversed = true, .link_edges = link_edges}; | ||||
| if (mp->totloop > largest_ngon) { | if (mp->totloop > largest_ngon) { | ||||
| largest_ngon = (uint)mp->totloop; | largest_ngon = (uint)mp->totloop; | ||||
| } | } | ||||
| /* add to final mesh face count */ | |||||
| if (do_shell) { | if (do_shell) { | ||||
| numNewPolys += 2; | numNewPolys += 2; | ||||
| numNewLoops += (uint)mp->totloop * 2; | numNewLoops += (uint)mp->totloop * 2; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| uint *edge_adj_faces_len = MEM_calloc_arrayN( | uint *edge_adj_faces_len = MEM_calloc_arrayN( | ||||
| Show All 13 Lines | #define MOD_SOLIDIFY_EMPTY_TAG ((uint)-1) | ||||
| NewEdgeRef ***orig_edge_data_arr = MEM_calloc_arrayN( | NewEdgeRef ***orig_edge_data_arr = MEM_calloc_arrayN( | ||||
| numEdges, sizeof(*orig_edge_data_arr), "orig_edge_data_arr in solidify"); | numEdges, sizeof(*orig_edge_data_arr), "orig_edge_data_arr in solidify"); | ||||
| /* Original edge length cache. */ | /* Original edge length cache. */ | ||||
| float *orig_edge_lengths = MEM_calloc_arrayN( | float *orig_edge_lengths = MEM_calloc_arrayN( | ||||
| numEdges, sizeof(*orig_edge_lengths), "orig_edge_lengths in solidify"); | numEdges, sizeof(*orig_edge_lengths), "orig_edge_lengths in solidify"); | ||||
| /* Edge groups for every original vert. */ | /* Edge groups for every original vert. */ | ||||
| EdgeGroup **orig_vert_groups_arr = MEM_calloc_arrayN( | EdgeGroup **orig_vert_groups_arr = MEM_calloc_arrayN( | ||||
| numVerts, sizeof(*orig_vert_groups_arr), "orig_vert_groups_arr in solidify"); | numVerts, sizeof(*orig_vert_groups_arr), "orig_vert_groups_arr in solidify"); | ||||
| /* Duplicate verts map. */ | /* vertex map used to map duplicates. */ | ||||
| uint *vm = MEM_malloc_arrayN(numVerts, sizeof(*vm), "orig_vert_map in solidify"); | uint *vm = MEM_malloc_arrayN(numVerts, sizeof(*vm), "orig_vert_map in solidify"); | ||||
| for (uint i = 0; i < numVerts; i++) { | for (uint i = 0; i < numVerts; i++) { | ||||
| vm[i] = i; | vm[i] = i; | ||||
| } | } | ||||
| uint edge_index = 0; | uint edge_index = 0; | ||||
| uint loop_index = 0; | uint loop_index = 0; | ||||
| uint poly_index = 0; | uint poly_index = 0; | ||||
| Show All 20 Lines | /* Create link_faces for edges. */ | ||||
| const uint edge = ml->e; | const uint edge = ml->e; | ||||
| const bool reversed = orig_medge[edge].v2 != ml->v; | const bool reversed = orig_medge[edge].v2 != ml->v; | ||||
| OldEdgeFaceRef *old_face_edge_ref = edge_adj_faces[edge]; | OldEdgeFaceRef *old_face_edge_ref = edge_adj_faces[edge]; | ||||
| if (old_face_edge_ref == NULL) { | if (old_face_edge_ref == NULL) { | ||||
| const uint len = edge_adj_faces_len[edge]; | const uint len = edge_adj_faces_len[edge]; | ||||
| BLI_assert(len > 0); | BLI_assert(len > 0); | ||||
| uint *adj_faces = MEM_malloc_arrayN( | uint *adj_faces = MEM_malloc_arrayN( | ||||
| len, sizeof(*adj_faces), "OldEdgeFaceRef::faces in solidify"); | len, sizeof(*adj_faces), "OldEdgeFaceRef::faces in solidify"); | ||||
| bool *adj_faces_loops_reversed = MEM_malloc_arrayN( | bool *adj_faces_reversed = MEM_malloc_arrayN( | ||||
| len, sizeof(*adj_faces_loops_reversed), "OldEdgeFaceRef::reversed in solidify"); | len, sizeof(*adj_faces_reversed), "OldEdgeFaceRef::reversed in solidify"); | ||||
| adj_faces[0] = i; | adj_faces[0] = i; | ||||
| for (uint k = 1; k < len; k++) { | for (uint k = 1; k < len; k++) { | ||||
| adj_faces[k] = MOD_SOLIDIFY_EMPTY_TAG; | adj_faces[k] = MOD_SOLIDIFY_EMPTY_TAG; | ||||
| } | } | ||||
| adj_faces_loops_reversed[0] = reversed; | adj_faces_reversed[0] = reversed; | ||||
| OldEdgeFaceRef *ref = MEM_mallocN(sizeof(*ref), "OldEdgeFaceRef in solidify"); | OldEdgeFaceRef *ref = MEM_mallocN(sizeof(*ref), "OldEdgeFaceRef in solidify"); | ||||
| *ref = (OldEdgeFaceRef){adj_faces, len, adj_faces_loops_reversed, 1}; | *ref = (OldEdgeFaceRef){adj_faces, len, adj_faces_reversed, 1}; | ||||
| edge_adj_faces[edge] = ref; | edge_adj_faces[edge] = ref; | ||||
| } | } | ||||
| else { | else { | ||||
| for (uint k = 1; k < old_face_edge_ref->faces_len; k++) { | for (uint k = 1; k < old_face_edge_ref->faces_len; k++) { | ||||
| if (old_face_edge_ref->faces[k] == MOD_SOLIDIFY_EMPTY_TAG) { | if (old_face_edge_ref->faces[k] == MOD_SOLIDIFY_EMPTY_TAG) { | ||||
| old_face_edge_ref->faces[k] = i; | old_face_edge_ref->faces[k] = i; | ||||
| old_face_edge_ref->faces_reversed[k] = reversed; | old_face_edge_ref->faces_reversed[k] = reversed; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| float edgedir[3] = {0, 0, 0}; | float edgedir[3] = {0, 0, 0}; | ||||
| /* Calculate edge lengths and len vert_adj edges. */ | /* Calculate edge lengths and len vert_adj edges. */ | ||||
| { | { | ||||
| bool *face_singularity = MEM_calloc_arrayN( | bool *face_singularity = MEM_calloc_arrayN( | ||||
| numPolys, sizeof(*face_singularity), "face_sides_arr in solidify"); | numPolys, sizeof(*face_singularity), "face_sides_arr in solidify"); | ||||
| ed = orig_medge; | ed = orig_medge; | ||||
| for (uint i = 0; i < numEdges; i++, ed++) { | for (uint i = 0; i < numEdges; i++, ed++) { | ||||
| if (edge_adj_faces_len[i] > 0) { | if (edge_adj_faces_len[i] > 0) { | ||||
| const uint v1 = vm[ed->v1]; | const uint v1 = vm[ed->v1]; | ||||
| const uint v2 = vm[ed->v2]; | const uint v2 = vm[ed->v2]; | ||||
| if (v1 != v2) { | if (v1 != v2) { | ||||
| sub_v3_v3v3(edgedir, orig_mvert[v2].co, orig_mvert[v1].co); | sub_v3_v3v3(edgedir, orig_mvert[v2].co, orig_mvert[v1].co); | ||||
| orig_edge_lengths[i] = len_squared_v3(edgedir); | orig_edge_lengths[i] = len_squared_v3(edgedir); | ||||
| } | } | ||||
| if (v1 == v2 || orig_edge_lengths[i] <= FLT_EPSILON) { | if (v1 != v2 && orig_edge_lengths[i] <= FLT_EPSILON) { | ||||
| if (v2 > v1) { | if (v2 > v1) { | ||||
| for (uint j = v2; j < numVerts; j++) { | for (uint j = v2; j < numVerts; j++) { | ||||
| if (vm[j] == v2) { | if (vm[j] == v2) { | ||||
| vm[j] = v1; | vm[j] = v1; | ||||
| vert_adj_edges_len[v1] += vert_adj_edges_len[j]; | vert_adj_edges_len[v1] += vert_adj_edges_len[j]; | ||||
| vert_adj_edges_len[j] = 0; | vert_adj_edges_len[j] = 0; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else if (v2 < v1) { | else if (v2 < v1) { | ||||
| for (uint j = v1; j < numVerts; j++) { | for (uint j = v1; j < numVerts; j++) { | ||||
| if (vm[j] == v1) { | if (vm[j] == v1) { | ||||
| vm[j] = v2; | vm[j] = v2; | ||||
| vert_adj_edges_len[v2] += vert_adj_edges_len[j]; | vert_adj_edges_len[v2] += vert_adj_edges_len[j]; | ||||
| vert_adj_edges_len[j] = 0; | vert_adj_edges_len[j] = 0; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (do_shell) { | if (do_shell) { | ||||
| numNewLoops -= edge_adj_faces_len[i] * 2; | numNewLoops -= edge_adj_faces_len[i] * 2; | ||||
| } | } | ||||
| if (v1 == v2) { | |||||
| edge_adj_faces_len[i] = 0; | |||||
| MEM_freeN(edge_adj_faces[i]->faces); | |||||
| MEM_freeN(edge_adj_faces[i]->faces_reversed); | |||||
| MEM_freeN(edge_adj_faces[i]); | |||||
| edge_adj_faces[i] = NULL; | |||||
| } | |||||
| else if (v1 != v2 && edge_adj_faces_len[i] > 0) { | |||||
| orig_edge_lengths[i] = sqrtf(orig_edge_lengths[i]); | |||||
| vert_adj_edges_len[v1]++; | |||||
| vert_adj_edges_len[v2]++; | |||||
| } | |||||
| } | |||||
| } | |||||
| /* remove zero faces in a second pass */ | |||||
| ed = orig_medge; | |||||
| for (uint i = 0; i < numEdges; i++, ed++) { | |||||
| const uint v1 = vm[ed->v1]; | |||||
| const uint v2 = vm[ed->v2]; | |||||
| if (v1 == v2 && edge_adj_faces[i]) { | |||||
| /* Remove polys. */ | /* Remove polys. */ | ||||
| for (uint j = 0; j < edge_adj_faces[i]->faces_len; j++) { | for (uint j = 0; j < edge_adj_faces[i]->faces_len; j++) { | ||||
| const uint face = edge_adj_faces[i]->faces[j]; | const uint face = edge_adj_faces[i]->faces[j]; | ||||
| if (!face_singularity[face]) { | if (!face_singularity[face]) { | ||||
| bool is_singularity = true; | bool is_singularity = true; | ||||
| for (uint k = 0; k < orig_mpoly[face].totloop; k++) { | for (uint k = 0; k < orig_mpoly[face].totloop; k++) { | ||||
| if (vm[orig_mloop[((uint)orig_mpoly[face].loopstart) + k].v] != v1) { | if (vm[orig_mloop[((uint)orig_mpoly[face].loopstart) + k].v] != v1) { | ||||
| is_singularity = false; | is_singularity = false; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| if (is_singularity) { | if (is_singularity) { | ||||
| face_singularity[face] = true; | face_singularity[face] = true; | ||||
| /* remove from final mesh poly count */ | |||||
| if (do_shell) { | if (do_shell) { | ||||
| numNewPolys -= 2; | numNewPolys -= 2; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (do_shell) { | |||||
| numNewLoops -= edge_adj_faces_len[i] * 2; | |||||
| } | } | ||||
| edge_adj_faces_len[i] = 0; | edge_adj_faces_len[i] = 0; | ||||
| MEM_freeN(edge_adj_faces[i]->faces); | MEM_freeN(edge_adj_faces[i]->faces); | ||||
| MEM_freeN(edge_adj_faces[i]->faces_reversed); | MEM_freeN(edge_adj_faces[i]->faces_reversed); | ||||
| MEM_freeN(edge_adj_faces[i]); | MEM_freeN(edge_adj_faces[i]); | ||||
| edge_adj_faces[i] = NULL; | edge_adj_faces[i] = NULL; | ||||
| } | } | ||||
| else if (edge_adj_faces_len[i] > 0) { | |||||
| orig_edge_lengths[i] = sqrtf(orig_edge_lengths[i]); | |||||
| vert_adj_edges_len[v1]++; | |||||
| vert_adj_edges_len[v2]++; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| MEM_freeN(face_singularity); | MEM_freeN(face_singularity); | ||||
| } | } | ||||
| /* Create vert_adj_edges for verts. */ | /* Create vert_adj_edges for verts. */ | ||||
| { | { | ||||
| ed = orig_medge; | ed = orig_medge; | ||||
| for (uint i = 0; i < numEdges; i++, ed++) { | for (uint i = 0; i < numEdges; i++, ed++) { | ||||
| if (edge_adj_faces_len[i] > 0) { | if (edge_adj_faces_len[i] > 0) { | ||||
| ▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | /* Create vert_adj_edges for verts. */ | ||||
| if (i_adj_faces->faces[k] == invalid_adj_faces->faces[l] && | if (i_adj_faces->faces[k] == invalid_adj_faces->faces[l] && | ||||
| i_adj_faces->faces[k] != MOD_SOLIDIFY_EMPTY_TAG) { | i_adj_faces->faces[k] != MOD_SOLIDIFY_EMPTY_TAG) { | ||||
| i_adj_faces->faces[k] = MOD_SOLIDIFY_EMPTY_TAG; | i_adj_faces->faces[k] = MOD_SOLIDIFY_EMPTY_TAG; | ||||
| invalid_adj_faces->faces[l] = MOD_SOLIDIFY_EMPTY_TAG; | invalid_adj_faces->faces[l] = MOD_SOLIDIFY_EMPTY_TAG; | ||||
| j++; | j++; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* remove from final face count */ | |||||
| if (do_shell) { | if (do_shell) { | ||||
| numNewPolys -= 2 * j; | numNewPolys -= 2 * j; | ||||
| numNewLoops -= 4 * j; | numNewLoops -= 4 * j; | ||||
| } | } | ||||
| const uint len = i_adj_faces->faces_len + invalid_adj_faces->faces_len - 2 * j; | const uint len = i_adj_faces->faces_len + invalid_adj_faces->faces_len - 2 * j; | ||||
| uint *adj_faces = MEM_malloc_arrayN( | uint *adj_faces = MEM_malloc_arrayN( | ||||
| len, sizeof(*adj_faces), "OldEdgeFaceRef::faces in solidify"); | len, sizeof(*adj_faces), "OldEdgeFaceRef::faces in solidify"); | ||||
| bool *adj_faces_loops_reversed = MEM_malloc_arrayN( | bool *adj_faces_loops_reversed = MEM_malloc_arrayN( | ||||
| ▲ Show 20 Lines • Show All 285 Lines • ▼ Show 20 Lines | for (uint i = 0; i < numVerts; i++, adj_edges_ptr++) { | ||||
| const uint tot_adj_edges = (*adj_edges_ptr)->edges_len; | const uint tot_adj_edges = (*adj_edges_ptr)->edges_len; | ||||
| uint unassigned_edges_len = 0; | uint unassigned_edges_len = 0; | ||||
| for (uint j = 0; j < tot_adj_edges; j++) { | for (uint j = 0; j < tot_adj_edges; j++) { | ||||
| NewEdgeRef **new_edges = orig_edge_data_arr[adj_edges[j]]; | NewEdgeRef **new_edges = orig_edge_data_arr[adj_edges[j]]; | ||||
| /* TODO check where the null pointer come from, | /* TODO check where the null pointer come from, | ||||
| * because there should not be any... */ | * because there should not be any... */ | ||||
| if (new_edges) { | if (new_edges) { | ||||
| /* count the number of new edges around the original vert */ | |||||
| while (*new_edges) { | while (*new_edges) { | ||||
| unassigned_edges_len++; | unassigned_edges_len++; | ||||
| new_edges++; | new_edges++; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| NewEdgeRef **unassigned_edges = MEM_malloc_arrayN( | NewEdgeRef **unassigned_edges = MEM_malloc_arrayN( | ||||
| unassigned_edges_len, sizeof(*unassigned_edges), "unassigned_edges in solidify"); | unassigned_edges_len, sizeof(*unassigned_edges), "unassigned_edges in solidify"); | ||||
| for (uint j = 0, k = 0; j < tot_adj_edges; j++) { | for (uint j = 0, k = 0; j < tot_adj_edges; j++) { | ||||
| NewEdgeRef **new_edges = orig_edge_data_arr[adj_edges[j]]; | NewEdgeRef **new_edges = orig_edge_data_arr[adj_edges[j]]; | ||||
| if (new_edges) { | if (new_edges) { | ||||
| while (*new_edges) { | while (*new_edges) { | ||||
| unassigned_edges[k++] = *new_edges; | unassigned_edges[k++] = *new_edges; | ||||
| new_edges++; | new_edges++; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* an edge group will always contain min 2 edges so max edge group count can be calculated */ | |||||
| uint edge_groups_len = unassigned_edges_len / 2; | |||||
| edge_groups = MEM_calloc_arrayN( | edge_groups = MEM_calloc_arrayN( | ||||
| (unassigned_edges_len / 2) + 1, sizeof(*edge_groups), "edge_groups in solidify"); | edge_groups_len + 1, sizeof(*edge_groups), "edge_groups in solidify"); | ||||
| uint assigned_edges_len = 0; | uint assigned_edges_len = 0; | ||||
| NewEdgeRef *found_edge = NULL; | NewEdgeRef *found_edge = NULL; | ||||
| uint found_edge_index = 0; | uint found_edge_index = 0; | ||||
| bool insert_at_start = false; | bool insert_at_start = false; | ||||
| uint eg_capacity = 5; | uint eg_capacity = 5; | ||||
| NewFaceRef *eg_track_faces[2] = {NULL, NULL}; | NewFaceRef *eg_track_faces[2] = {NULL, NULL}; | ||||
| NewFaceRef *last_open_edge_track = NULL; | NewFaceRef *last_open_edge_track = NULL; | ||||
| NewEdgeRef *edge = NULL; | |||||
| while (assigned_edges_len < unassigned_edges_len) { | while (assigned_edges_len < unassigned_edges_len) { | ||||
| found_edge = NULL; | found_edge = NULL; | ||||
| insert_at_start = false; | insert_at_start = false; | ||||
| if (eg_index >= 0 && edge_groups[eg_index].edges_len == 0) { | if (eg_index >= 0 && edge_groups[eg_index].edges_len == 0) { | ||||
| /* called everytime a new group was started in the last iteration */ | |||||
| /* find an unused edge to start the next group and setup variables to start creating it */ | |||||
| uint j = 0; | uint j = 0; | ||||
| edge = NULL; | NewEdgeRef *edge = NULL; | ||||
| while (!edge && j < unassigned_edges_len) { | while (!edge && j < unassigned_edges_len) { | ||||
| edge = unassigned_edges[j++]; | edge = unassigned_edges[j++]; | ||||
| if (edge && last_open_edge_track && | if (edge && last_open_edge_track && | ||||
| (edge->faces[0] != last_open_edge_track || edge->faces[1] != NULL)) { | (edge->faces[0] != last_open_edge_track || edge->faces[1] != NULL)) { | ||||
| edge = NULL; | edge = NULL; | ||||
| } | } | ||||
| } | } | ||||
| if (!edge && last_open_edge_track) { | if (!edge && last_open_edge_track) { | ||||
| Show All 25 Lines | for (uint i = 0; i < numVerts; i++, adj_edges_ptr++) { | ||||
| eg_track_faces[1] = edge->faces[0]; | eg_track_faces[1] = edge->faces[0]; | ||||
| } | } | ||||
| } | } | ||||
| else if (eg_index >= 0) { | else if (eg_index >= 0) { | ||||
| NewEdgeRef **edge_ptr = unassigned_edges; | NewEdgeRef **edge_ptr = unassigned_edges; | ||||
| for (found_edge_index = 0; found_edge_index < unassigned_edges_len; | for (found_edge_index = 0; found_edge_index < unassigned_edges_len; | ||||
| found_edge_index++, edge_ptr++) { | found_edge_index++, edge_ptr++) { | ||||
| if (*edge_ptr) { | if (*edge_ptr) { | ||||
| edge = *edge_ptr; | NewEdgeRef *edge = *edge_ptr; | ||||
| if (edge->faces[0] == eg_track_faces[1]) { | if (edge->faces[0] == eg_track_faces[1]) { | ||||
| insert_at_start = false; | insert_at_start = false; | ||||
| eg_track_faces[1] = edge->faces[1]; | eg_track_faces[1] = edge->faces[1]; | ||||
| found_edge = edge; | found_edge = edge; | ||||
| if (edge->faces[1] == NULL) { | if (edge->faces[1] == NULL) { | ||||
| edge_groups[eg_index].is_orig_closed = false; | edge_groups[eg_index].is_orig_closed = false; | ||||
| last_open_edge_track = edge->faces[0]->reversed ? edge->faces[0] - 1 : | last_open_edge_track = edge->faces[0]->reversed ? edge->faces[0] - 1 : | ||||
| edge->faces[0] + 1; | edge->faces[0] + 1; | ||||
| ▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | for (uint i = 0; i < numVerts; i++, adj_edges_ptr++) { | ||||
| NULL) { | NULL) { | ||||
| last_open_edge_track = NULL; | last_open_edge_track = NULL; | ||||
| } | } | ||||
| if (edge_groups[eg_index].edges_len > 3) { | if (edge_groups[eg_index].edges_len > 3) { | ||||
| contains_long_groups = true; | contains_long_groups = true; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* called on first iteration to clean up the eg_index = -1 and start the first group, | |||||
| * or when the current group is found to be complete (no new found_edge) */ | |||||
| eg_index++; | eg_index++; | ||||
| BLI_assert(eg_index < (unassigned_edges_len / 2)); | BLI_assert(eg_index < edge_groups_len); | ||||
| eg_capacity = 5; | eg_capacity = 5; | ||||
| NewEdgeRef **edges = MEM_calloc_arrayN( | NewEdgeRef **edges = MEM_calloc_arrayN( | ||||
| eg_capacity, sizeof(*edges), "edge_group in solidify"); | eg_capacity, sizeof(*edges), "edge_group in solidify"); | ||||
| edge_groups[eg_index] = (EdgeGroup){ | edge_groups[eg_index] = (EdgeGroup){ | ||||
| .valid = true, | .valid = true, | ||||
| .edges = edges, | .edges = edges, | ||||
| .edges_len = 0, | .edges_len = 0, | ||||
| .open_face_edge = MOD_SOLIDIFY_EMPTY_TAG, | .open_face_edge = MOD_SOLIDIFY_EMPTY_TAG, | ||||
| Show All 9 Lines | for (uint i = 0; i < numVerts; i++, adj_edges_ptr++) { | ||||
| eg_track_faces[0] = NULL; | eg_track_faces[0] = NULL; | ||||
| eg_track_faces[1] = NULL; | eg_track_faces[1] = NULL; | ||||
| } | } | ||||
| } | } | ||||
| /* #eg_index is the number of groups from here on. */ | /* #eg_index is the number of groups from here on. */ | ||||
| eg_index++; | eg_index++; | ||||
| /* #topo_groups is the number of topo groups from here on. */ | /* #topo_groups is the number of topo groups from here on. */ | ||||
| topo_groups++; | topo_groups++; | ||||
| MEM_freeN(unassigned_edges); | MEM_freeN(unassigned_edges); | ||||
| /* TODO reshape the edge_groups array to its actual size after writing is finished to save on memory */ | |||||
| } | } | ||||
| /* Split of long self intersection groups */ | /* Split of long self intersection groups */ | ||||
| { | { | ||||
| uint splits = 0; | uint splits = 0; | ||||
| if (contains_long_groups) { | if (contains_long_groups) { | ||||
| uint add_index = 0; | uint add_index = 0; | ||||
| for (uint j = 0; j < eg_index; j++) { | for (uint j = 0; j < eg_index; j++) { | ||||
| ▲ Show 20 Lines • Show All 812 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| if (singularity_edges) { | if (singularity_edges) { | ||||
| MEM_freeN(singularity_edges); | MEM_freeN(singularity_edges); | ||||
| } | } | ||||
| /* DEBUG CODE FOR BUGFIXING (can not be removed because every bugfix needs this badly!). */ | /* DEBUG CODE FOR BUGFIXING (can not be removed because every bugfix needs this badly!). */ | ||||
| #if 0 | #if 0 | ||||
| { | { | ||||
| /* this code will output the content of orig_vert_groups_arr. | |||||
| * in orig_vert_groups_arr these conditions must be met for every vertex: | |||||
| * - new_edge value should have no duplicates | |||||
| * - every old_edge value should appear twice | |||||
| * - every group should have at least two members (edges) | |||||
| * Note: that there can be vertices that only have one group. They are called singularities. | |||||
| * These vertices will only have one side (there is no way of telling apart front | |||||
| * from back like on a mobius strip) | |||||
| */ | |||||
| /* Debug output format: | |||||
| * <original vertex id>: | |||||
| * { | |||||
| * { <old edge id>/<new edge id>, } (tg:<topology group id>)(s:<is split group>,c:<is closed group (before splitting)>) | |||||
| * } | |||||
| */ | |||||
| gs_ptr = orig_vert_groups_arr; | gs_ptr = orig_vert_groups_arr; | ||||
| for (uint i = 0; i < numVerts; i++, gs_ptr++) { | for (uint i = 0; i < numVerts; i++, gs_ptr++) { | ||||
| EdgeGroup *gs = *gs_ptr; | EdgeGroup *gs = *gs_ptr; | ||||
| /* check if the vertex is present (may be dissolved because of proximity) */ | |||||
| if (gs) { | if (gs) { | ||||
| printf("%d:\n", i); | |||||
| for (EdgeGroup *g = gs; g->valid; g++) { | for (EdgeGroup *g = gs; g->valid; g++) { | ||||
| NewEdgeRef **e = g->edges; | NewEdgeRef **e = g->edges; | ||||
| for (uint j = 0; j < g->edges_len; j++, e++) { | for (uint j = 0; j < g->edges_len; j++, e++) { | ||||
| printf("%u/%d, ", (*e)->old_edge, (int)(*e)->new_edge); | printf("%u/%d, ", (*e)->old_edge, (int)(*e)->new_edge); | ||||
| } | } | ||||
| printf("(tg:%u)(s:%u,c:%d)\n", g->topo_group, g->split, g->is_orig_closed); | printf("(tg:%u)(s:%u,c:%d)\n", g->topo_group, g->split, g->is_orig_closed); | ||||
| } | } | ||||
| printf("\n"); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| #endif | #endif | ||||
| /* Make boundary edges/faces. */ | /* Make boundary edges/faces. */ | ||||
| { | { | ||||
| gs_ptr = orig_vert_groups_arr; | gs_ptr = orig_vert_groups_arr; | ||||
| ▲ Show 20 Lines • Show All 440 Lines • Show Last 20 Lines | |||||