diff options
Diffstat (limited to 'source/blender/modifiers/intern/MOD_edgesplit.c')
-rw-r--r-- | source/blender/modifiers/intern/MOD_edgesplit.c | 204 |
1 files changed, 191 insertions, 13 deletions
diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c index bbb314cc085..c98905a8be1 100644 --- a/source/blender/modifiers/intern/MOD_edgesplit.c +++ b/source/blender/modifiers/intern/MOD_edgesplit.c @@ -323,10 +323,189 @@ DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd) vu = etags[ml->e].v1user; vu2 = etags[ml->e].v2user; +<<<<<<< .working if (vu) medge[ml->e].v1 = vu->v; if (vu2) medge[ml->e].v2 = vu2->v; +======= +/* finds another sharp edge which uses vert, by traversing faces around the + * vert until it does one of the following: + * - hits a loose edge (the edge is returned) + * - hits a sharp edge (the edge is returned) + * - returns to the start edge (NULL is returned) + */ +static SmoothEdge *find_other_sharp_edge(SmoothVert *vert, SmoothEdge *edge, LinkNode **visited_faces) +{ + SmoothFace *face = NULL; + SmoothEdge *edge2 = NULL; + /* holds the edges we've seen so we can avoid looping indefinitely */ + LinkNode *visited_edges = NULL; +#ifdef EDGESPLIT_DEBUG_1 + printf("=== START === find_other_sharp_edge(edge = %4d, vert = %4d)\n", + edge->newIndex, vert->newIndex); +#endif + + /* get a face on which to start */ + if(edge->faces) face = edge->faces->link; + else return NULL; + + /* record this edge as visited */ + BLI_linklist_prepend(&visited_edges, edge); + + /* get the next edge */ + edge2 = other_edge(face, vert, edge); + + /* record this face as visited */ + if(visited_faces) + BLI_linklist_prepend(visited_faces, face); + + /* search until we hit a loose edge or a sharp edge or an edge we've + * seen before + */ + while(face && !edge_is_sharp(edge2) + && !linklist_contains(visited_edges, edge2)) { +#ifdef EDGESPLIT_DEBUG_3 + printf("current face %4d; current edge %4d\n", face->newIndex, + edge2->newIndex); +#endif + /* get the next face */ + face = other_face(edge2, face); + + /* if face == NULL, edge2 is a loose edge */ + if(face) { + /* record this face as visited */ + if(visited_faces) + BLI_linklist_prepend(visited_faces, face); + + /* record this edge as visited */ + BLI_linklist_prepend(&visited_edges, edge2); + + /* get the next edge */ + edge2 = other_edge(face, vert, edge2); +#ifdef EDGESPLIT_DEBUG_3 + printf("next face %4d; next edge %4d\n", + face->newIndex, edge2->newIndex); + } else { + printf("loose edge: %4d\n", edge2->newIndex); +#endif + } + } + + /* either we came back to the start edge or we found a sharp/loose edge */ + if(linklist_contains(visited_edges, edge2)) + /* we came back to the start edge */ + edge2 = NULL; + + BLI_linklist_free(visited_edges, NULL); + +#ifdef EDGESPLIT_DEBUG_1 + printf("=== END === find_other_sharp_edge(edge = %4d, vert = %4d), " + "returning edge %d\n", + edge->newIndex, vert->newIndex, edge2 ? edge2->newIndex : -1); +#endif + return edge2; +} + +static void split_single_vert(SmoothVert *vert, SmoothFace *face, + SmoothMesh *mesh) +{ + SmoothVert *copy_vert; + ReplaceData repdata; + + copy_vert = smoothvert_copy(vert, mesh); + + if(copy_vert == NULL) { + /* bug [#26316], this prevents a segfault + * but this still needs fixing */ + return; + } + + repdata.find = vert; + repdata.replace = copy_vert; + face_replace_vert(face, &repdata); +} + +typedef struct PropagateEdge { + struct PropagateEdge *next, *prev; + SmoothEdge *edge; + SmoothVert *vert; +} PropagateEdge; + +static void push_propagate_stack(SmoothEdge *edge, SmoothVert *vert, SmoothMesh *mesh) +{ + PropagateEdge *pedge = mesh->reusestack.first; + + if(pedge) { + BLI_remlink(&mesh->reusestack, pedge); + } + else { + if(!mesh->arena) { + mesh->arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "edgesplit arena"); + BLI_memarena_use_calloc(mesh->arena); + } + + pedge = BLI_memarena_alloc(mesh->arena, sizeof(PropagateEdge)); + } + + pedge->edge = edge; + pedge->vert = vert; + BLI_addhead(&mesh->propagatestack, pedge); +} + +static void pop_propagate_stack(SmoothEdge **edge, SmoothVert **vert, SmoothMesh *mesh) +{ + PropagateEdge *pedge = mesh->propagatestack.first; + + if(pedge) { + *edge = pedge->edge; + *vert = pedge->vert; + BLI_remlink(&mesh->propagatestack, pedge); + BLI_addhead(&mesh->reusestack, pedge); + } + else { + *edge = NULL; + *vert = NULL; + } +} + +static void split_edge(SmoothEdge *edge, SmoothVert *vert, SmoothMesh *mesh); + +static void propagate_split(SmoothEdge *edge, SmoothVert *vert, + SmoothMesh *mesh) +{ + SmoothEdge *edge2; + LinkNode *visited_faces = NULL; +#ifdef EDGESPLIT_DEBUG_1 + printf("=== START === propagate_split(edge = %4d, vert = %4d)\n", + edge->newIndex, vert->newIndex); +#endif + + edge2 = find_other_sharp_edge(vert, edge, &visited_faces); + + if(!edge2) { + /* didn't find a sharp or loose edge, so we've hit a dead end */ + } else if(!edge_is_loose(edge2)) { + /* edge2 is not loose, so it must be sharp */ + if(edge_is_loose(edge)) { + /* edge is loose, so we can split edge2 at this vert */ + split_edge(edge2, vert, mesh); + } else if(edge_is_sharp(edge)) { + /* both edges are sharp, so we can split the pair at vert */ + split_edge(edge, vert, mesh); + } else { + /* edge is not sharp, so try to split edge2 at its other vert */ + split_edge(edge2, other_vert(edge2, vert), mesh); + } + } else { /* edge2 is loose */ + if(edge_is_loose(edge)) { + SmoothVert *vert2; + ReplaceData repdata; + + /* can't split edge, what should we do with vert? */ + if(linklist_subset(vert->faces, visited_faces)) { + /* vert has only one fan of faces attached; don't split it */ +>>>>>>> .merge-right.r36153 } else { etags[ml->e].used = 1; @@ -384,7 +563,6 @@ DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd) return cddm; } - static void initData(ModifierData *md) { EdgeSplitModifierData *emd = (EdgeSplitModifierData*) md; @@ -447,19 +625,19 @@ ModifierTypeInfo modifierType_EdgeSplit = { | eModifierTypeFlag_EnableInEditmode, /* copyData */ copyData, - /* deformVerts */ 0, - /* deformMatrices */ 0, - /* deformVertsEM */ 0, - /* deformMatricesEM */ 0, + /* deformVerts */ NULL, + /* deformMatrices */ NULL, + /* deformVertsEM */ NULL, + /* deformMatricesEM */ NULL, /* applyModifier */ applyModifier, /* applyModifierEM */ applyModifierEM, /* initData */ initData, - /* requiredDataMask */ 0, - /* freeData */ 0, - /* isDisabled */ 0, - /* updateDepgraph */ 0, - /* dependsOnTime */ 0, - /* dependsOnNormal */ 0, - /* foreachObjectLink */ 0, - /* foreachIDLink */ 0, + /* requiredDataMask */ NULL, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepgraph */ NULL, + /* dependsOnTime */ NULL, + /* dependsOnNormals */ NULL, + /* foreachObjectLink */ NULL, + /* foreachIDLink */ NULL, }; |