#17873: "switch direction" for bones can cause infinite loop
authorJoshua Leung <aligorith@gmail.com>
Tue, 21 Oct 2008 01:40:47 +0000 (01:40 +0000)
committerJoshua Leung <aligorith@gmail.com>
Tue, 21 Oct 2008 01:40:47 +0000 (01:40 +0000)
Second attempt at fixing this bug. Previous fix caused segfault when all bones in a chain are selected. Now it should segments which are selected (i.e. get swapped) will get unparented from segments that aren't (i.e. aren't swapped, so are still in old orientation)

source/blender/src/editarmature.c

index ef6be4a010d1f028f73ac021cc8debc936101f8e..61ca5c098771daa5296461ac01cb622a74b51862 100644 (file)
@@ -3277,7 +3277,8 @@ void switch_direction_armature (void)
                EditBone *ebo, *child=NULL, *parent=NULL;
                
                /* loop over bones in chain */
-               for (ebo= chain->data; ebo; child= ebo, ebo=parent) {
+               for (ebo= chain->data; ebo;) {
+                       /* parent is this bone's original parent (to go to next if we swap) */
                        parent= ebo->parent;
                        
                        /* only if selected and editable */
@@ -3297,12 +3298,28 @@ void switch_direction_armature (void)
                                else    
                                        ebo->flag &= ~BONE_CONNECTED;
                                
-                               child->parent = NULL;
-                               child->flag &= ~BONE_CONNECTED;
-
-                               /* FIXME: other things that need fixing?
-                                *              i.e. roll?
+                               /* get next bones 
+                                *      - child will become the new parent of next bone
+                                *      - next bone to go to will be the original parent
+                                */
+                               child= ebo;
+                               ebo= parent;
+                       }
+                       else {
+                               /* not swapping this bone, however, if its 'parent' got swapped, unparent us from it 
+                                * as it will be facing in opposite direction
+                                */
+                               if ((parent) && (EBONE_VISIBLE(arm, parent) && EBONE_EDITABLE(parent))) {
+                                       ebo->parent= NULL;
+                                       ebo->flag &= ~BONE_CONNECTED;
+                               }
+                               
+                               /* get next bones
+                                *      - child will become new parent of next bone (not swapping occurred, so set to NULL to prevent infinite-loop)
+                                *      - next bone to go to will be the original parent (no change)
                                 */
+                               child= NULL;
+                               ebo= parent;
                        }
                }
        }