changeset 1163:c23593881507

Merge. Fix a bug to select the tween without key frame after it.
author wycc
date Tue, 28 Dec 2010 22:26:11 +0800
parents 64c54ef39480 (current diff) a7faab54e8f8 (diff)
children 2cb5047d8f2b
files pyink/MBScene.py pyink/frameline.py pyink/primitive_test.svg pyink/tween.py
diffstat 4 files changed, 227 insertions(+), 529 deletions(-) [+]
line wrap: on
line diff
--- a/pyink/MBScene.py	Mon Dec 27 23:20:13 2010 +0800
+++ b/pyink/MBScene.py	Tue Dec 28 22:26:11 2010 +0800
@@ -86,7 +86,7 @@
         if self.type == 'DOMSubtreeModified':
 	    self.func(node)
     def notifyAttributeChanged(self,node, name, old_value, new_value):
-        print 'attr',node,name,old_value,new_value
+        # print 'attr',node,name,old_value,new_value
         if self.type == 'DOMAttrModified':
 	    self.func(node,name)
 
@@ -336,6 +336,8 @@
 		        try:
 			    label = scene.getAttribute('inkscape:label')
 			    if label == 'dup':
+				# XXX: This would stop animation.
+				# This function is called by updateUI()
 			        node.removeChild(scene)
 			except:
 			    pass
@@ -603,9 +605,12 @@
 		    
 		    next_idx, next_stop_idx, next_tween_type = \
 			layer.get_frame_block(stop_idx + 1)
-		    next_scene_group = layer.get_frame_data(next_idx)
+		    if next_idx == -1:
+			next_scene_group = scene_group
+		    else:
+			next_scene_group = layer.get_frame_data(next_idx)
 		    
-		    nframes = next_idx - start_idx + 1
+		    nframes = stop_idx - start_idx + 1
 		    percent = float(idx - start_idx) / nframes
 		    self.tween.updateTweenContent(layer.duplicateGroup,
 						  tween_obj_tween_type,
@@ -873,16 +878,22 @@
 	"""
 	if self.btnRun.get_label() == "Run":
 	    self.btnRun.set_label("Stop")
+	    self.lockui = True
             self.last_update = glib.timeout_add(1000/self.framerate,self.doRunNext)
 	else:
 	    self.btnRun.set_label("Run")
 	    glib.source_remove(self.last_update)
+	    self.lockui = False
+	    pass
 
     def doRunNext(self):
 	if self.current >= self.maxframe:
 	    self.current = 0
-	print self.current,self.maxframe
-	self.setCurrentScene(self.current+1)
+	try:
+	    self.setCurrentScene(self.current+1)
+	except:
+	    traceback.print_exc()
+	    raise
         self.last_update = glib.timeout_add(1000/self.framerate,self.doRunNext)
         
     
@@ -917,10 +928,11 @@
 	if self.last_line == None:
 	    return
 	frameline = self.last_line
+	idx = self.last_frame
         i = 0
 	found = -1
 	for start_idx, stop_idx, tween_type in frameline.get_frame_blocks():
-	    if start_idx < stop_idx:
+	    if start_idx <= idx and stop_idx >= idx:
 		n = self.tweenTypeSelector.get_active()
 		new_tween_type = MBScene._frameline_tween_types[n]
 		self.last_line.set_tween_type(start_idx, new_tween_type)
--- a/pyink/frameline.py	Mon Dec 27 23:20:13 2010 +0800
+++ b/pyink/frameline.py	Tue Dec 28 22:26:11 2010 +0800
@@ -370,6 +370,12 @@
 		self._draw_tween(first_tween_key.idx, last_tween_key.idx,
 				 first_tween_key.right_tween_type)
 		last_tween_key = self._keys[last_tween_pos]
+		key_pos = last_tween_pos + 1
+		try:
+		    key = self._keys[key_pos]
+		except:
+		    key = keyframe(self._num_frames)
+		    pass
                 i = last_tween_key.idx + 1
 	    else:
                 self._draw_normal_frame(i)
@@ -704,7 +710,8 @@
 		block = (key.idx, next_key.idx, key.right_tween_type)
 	    elif not key.left_tween:
 		block = (key.idx, key.idx, 0)
-		pass
+	    else:
+		continue
 	    blocks.append(block)
 	    pass
 	return blocks
@@ -713,11 +720,14 @@
 	pos = self._find_keyframe_floor(idx)
 	if pos != -1:
 	    key = self._keys[pos]
+	    print key.right_tween, key.left_tween
 	    if key.idx == idx:
 		return key.idx, key.idx, 0
 	    elif key.right_tween:
 		next_key = self._keys[pos + 1]
 		return key.idx, next_key.idx, key.right_tween_type
+	    else:
+		return -1,-1,-1
 	    pass
 	raise ValueError, \
 	    'the frame specified by idx is not in any tween or a key frame'
--- a/pyink/primitive_test.svg	Mon Dec 27 23:20:13 2010 +0800
+++ b/pyink/primitive_test.svg	Tue Dec 28 22:26:11 2010 +0800
@@ -55,26 +55,17 @@
          ref="icon3s1983"
          type="scale" />
       <ns0:scene
-         start="1"
-         end="5"
-         ref="icon3s1983"
-         type="scale" />
-      <ns0:scene
          start="6"
          end="15"
          ref="icon3s9667"
-         type="normal" />
-      <ns0:scene
-         start="6"
-         end="15"
-         ref="icon3s9667"
-         type="normal" />
+         type="scale" />
       <ns0:scene
          start="16"
          ref="icon3s9194"
          type="normal" />
       <ns0:scene
          start="1"
+         end="21"
          ref="icon2s5149"
          type="normal" />
       <ns0:scene
@@ -83,20 +74,10 @@
          ref="icon1s6535"
          type="scale" />
       <ns0:scene
-         start="1"
-         end="10"
-         ref="icon1s6535"
-         type="scale" />
-      <ns0:scene
          start="11"
          end="20"
          ref="icon1s5911"
-         type="normal" />
-      <ns0:scene
-         start="11"
-         end="20"
-         ref="icon1s5911"
-         type="normal" />
+         type="scale" />
       <ns0:scene
          start="21"
          ref="icon1s3"
@@ -106,11 +87,6 @@
          end="8"
          ref="Layer 1s1983"
          type="scale" />
-      <ns0:scene
-         start="1"
-         end="8"
-         ref="Layer 1s1983"
-         type="scale" />
     </ns0:scenes>
   </metadata>
   <g
@@ -133,8 +109,8 @@
     <g
        inkscape:label="dup"
        sodipodi:insensitive="1"
-       style=""
-       id="g3905" />
+       style="display:none"
+       id="g3701" />
   </g>
   <g
      inkscape:groupmode="layer"
@@ -192,140 +168,22 @@
        inkscape:label="dup"
        sodipodi:insensitive="1"
        style=""
-       id="g3899">
-      <g
-         ref="path3105"
-         id="g3901"
-         transform="matrix(1,0,0,1,0,15.5844)">
-        <path
-           d="m 102.85714,46.647896 c 0,15.779564 -13.11166,28.571428 -29.285714,28.571428 -16.174053,0 -29.285715,-12.791864 -29.285715,-28.571428 0,-15.779564 13.111662,-28.571428 29.285715,-28.571428 16.174054,0 29.285714,12.791864 29.285714,28.571428 z"
-           sodipodi:ry="28.571428"
-           sodipodi:rx="29.285715"
-           sodipodi:cy="46.647896"
-           sodipodi:cx="73.571426"
-           id="path3903"
-           style="fill:#999999;fill-opacity:1"
-           sodipodi:type="arc" />
-      </g>
-      <g
-         id="g3923">
-        <path
-           transform="translate(0,85.714286)"
-           ns0:duplicate-src="path3105"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1"
-           id="path3925"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3112" />
-      </g>
+       id="g3695">
       <g
-         id="g3927">
-        <path
-           transform="translate(0,85.714286)"
-           ns0:duplicate-src="path3105"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1"
-           id="path3929"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3112" />
-      </g>
-      <g
-         id="g3939">
-        <path
-           transform="translate(0,85.714286)"
-           ns0:duplicate-src="path3105"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1"
-           id="path3941"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3112" />
-      </g>
-      <g
-         id="g3943">
+         ref="path3112"
+         id="g3723"
+         transform="matrix(1,0,0,1,0,0)">
         <path
            transform="translate(0,85.714286)"
            ns0:duplicate-src="path3105"
            sodipodi:type="arc"
            style="fill:#999999;fill-opacity:1"
-           id="path3945"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3112" />
-      </g>
-      <g
-         id="g3955">
-        <path
-           transform="translate(0,85.714286)"
-           ns0:duplicate-src="path3105"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1"
-           id="path3957"
+           id="path3725"
            sodipodi:cx="73.571426"
            sodipodi:cy="46.647896"
            sodipodi:rx="29.285715"
            sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3112" />
-      </g>
-      <g
-         id="g3959">
-        <path
-           transform="translate(0,85.714286)"
-           ns0:duplicate-src="path3105"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1"
-           id="path3961"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3112" />
-      </g>
-      <g
-         id="g3971">
-        <path
-           transform="translate(0,85.714286)"
-           ns0:duplicate-src="path3105"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1"
-           id="path3973"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3112" />
-      </g>
-      <g
-         id="g3975">
-        <path
-           transform="translate(0,85.714286)"
-           ns0:duplicate-src="path3105"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1"
-           id="path3977"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3112" />
+           d="m 102.85714,46.647896 c 0,15.779564 -13.11166,28.571428 -29.285714,28.571428 -16.174053,0 -29.285715,-12.791864 -29.285715,-28.571428 0,-15.779564 13.111662,-28.571428 29.285715,-28.571428 16.174054,0 29.285714,12.791864 29.285714,28.571428 z" />
       </g>
     </g>
   </g>
@@ -336,7 +194,7 @@
     <g
        id="icon2s5149"
        inkscape:groupmode="layer"
-       style="display: none">
+       style="display:none">
       <path
          transform="translate(86.428574,1.4285721)"
          sodipodi:type="arc"
@@ -351,8 +209,177 @@
     <g
        inkscape:label="dup"
        sodipodi:insensitive="1"
-       style="display:none"
-       id="g3897" />
+       style=""
+       id="g3689">
+      <g
+         id="g3691">
+        <path
+           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
+           sodipodi:ry="28.571428"
+           sodipodi:rx="29.285715"
+           sodipodi:cy="46.647896"
+           sodipodi:cx="73.571426"
+           id="path3693"
+           style="fill:#999999;fill-opacity:1;display:inline"
+           sodipodi:type="arc"
+           transform="translate(86.428574,1.4285721)"
+           ref="path3105-1" />
+      </g>
+      <g
+         id="g3707">
+        <path
+           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
+           sodipodi:ry="28.571428"
+           sodipodi:rx="29.285715"
+           sodipodi:cy="46.647896"
+           sodipodi:cx="73.571426"
+           id="path3709"
+           style="fill:#999999;fill-opacity:1;display:inline"
+           sodipodi:type="arc"
+           transform="translate(86.428574,1.4285721)"
+           ref="path3105-1" />
+      </g>
+      <g
+         id="g3711">
+        <path
+           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
+           sodipodi:ry="28.571428"
+           sodipodi:rx="29.285715"
+           sodipodi:cy="46.647896"
+           sodipodi:cx="73.571426"
+           id="path3713"
+           style="fill:#999999;fill-opacity:1;display:inline"
+           sodipodi:type="arc"
+           transform="translate(86.428574,1.4285721)"
+           ref="path3105-1" />
+      </g>
+      <g
+         id="g3715">
+        <path
+           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
+           sodipodi:ry="28.571428"
+           sodipodi:rx="29.285715"
+           sodipodi:cy="46.647896"
+           sodipodi:cx="73.571426"
+           id="path3717"
+           style="fill:#999999;fill-opacity:1;display:inline"
+           sodipodi:type="arc"
+           transform="translate(86.428574,1.4285721)"
+           ref="path3105-1" />
+      </g>
+      <g
+         id="g3719">
+        <path
+           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
+           sodipodi:ry="28.571428"
+           sodipodi:rx="29.285715"
+           sodipodi:cy="46.647896"
+           sodipodi:cx="73.571426"
+           id="path3721"
+           style="fill:#999999;fill-opacity:1;display:inline"
+           sodipodi:type="arc"
+           transform="translate(86.428574,1.4285721)"
+           ref="path3105-1" />
+      </g>
+      <g
+         id="g3727">
+        <path
+           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
+           sodipodi:ry="28.571428"
+           sodipodi:rx="29.285715"
+           sodipodi:cy="46.647896"
+           sodipodi:cx="73.571426"
+           id="path3729"
+           style="fill:#999999;fill-opacity:1;display:inline"
+           sodipodi:type="arc"
+           transform="translate(86.428574,1.4285721)"
+           ref="path3105-1" />
+      </g>
+      <g
+         id="g3731">
+        <path
+           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
+           sodipodi:ry="28.571428"
+           sodipodi:rx="29.285715"
+           sodipodi:cy="46.647896"
+           sodipodi:cx="73.571426"
+           id="path3733"
+           style="fill:#999999;fill-opacity:1;display:inline"
+           sodipodi:type="arc"
+           transform="translate(86.428574,1.4285721)"
+           ref="path3105-1" />
+      </g>
+      <g
+         id="g3735">
+        <path
+           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
+           sodipodi:ry="28.571428"
+           sodipodi:rx="29.285715"
+           sodipodi:cy="46.647896"
+           sodipodi:cx="73.571426"
+           id="path3737"
+           style="fill:#999999;fill-opacity:1;display:inline"
+           sodipodi:type="arc"
+           transform="translate(86.428574,1.4285721)"
+           ref="path3105-1" />
+      </g>
+      <g
+         id="g3739">
+        <path
+           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
+           sodipodi:ry="28.571428"
+           sodipodi:rx="29.285715"
+           sodipodi:cy="46.647896"
+           sodipodi:cx="73.571426"
+           id="path3741"
+           style="fill:#999999;fill-opacity:1;display:inline"
+           sodipodi:type="arc"
+           transform="translate(86.428574,1.4285721)"
+           ref="path3105-1" />
+      </g>
+      <g
+         id="g3743">
+        <path
+           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
+           sodipodi:ry="28.571428"
+           sodipodi:rx="29.285715"
+           sodipodi:cy="46.647896"
+           sodipodi:cx="73.571426"
+           id="path3745"
+           style="fill:#999999;fill-opacity:1;display:inline"
+           sodipodi:type="arc"
+           transform="translate(86.428574,1.4285721)"
+           ref="path3105-1" />
+      </g>
+      <g
+         id="g3747">
+        <path
+           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
+           sodipodi:ry="28.571428"
+           sodipodi:rx="29.285715"
+           sodipodi:cy="46.647896"
+           sodipodi:cx="73.571426"
+           id="path3749"
+           style="fill:#999999;fill-opacity:1;display:inline"
+           sodipodi:type="arc"
+           transform="translate(86.428574,1.4285721)"
+           ref="path3105-1" />
+      </g>
+      <g
+         id="g3751">
+        <path
+           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
+           sodipodi:ry="28.571428"
+           sodipodi:rx="29.285715"
+           sodipodi:cy="46.647896"
+           sodipodi:cx="73.571426"
+           id="path3753"
+           style="fill:#999999;fill-opacity:1;display:inline"
+           sodipodi:type="arc"
+           transform="translate(86.428574,1.4285721)"
+           ref="path3105-1" />
+      </g>
+    </g>
   </g>
   <g
      inkscape:groupmode="layer"
@@ -411,381 +438,22 @@
        inkscape:label="dup"
        sodipodi:insensitive="1"
        style=""
-       id="g3887">
-      <g
-         id="g3889">
-        <path
-           ns0:duplicate-src="path3105-0"
-           transform="translate(177.85715,2.8571441)"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           id="path3891"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
-      <g
-         id="g3893">
-        <path
-           ns0:duplicate-src="path3105-0"
-           transform="translate(177.85715,2.8571441)"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           id="path3895"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
-      <g
-         id="g3907">
-        <path
-           ns0:duplicate-src="path3105-0"
-           transform="translate(177.85715,2.8571441)"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           id="path3909"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
-      <g
-         id="g3911">
-        <path
-           ns0:duplicate-src="path3105-0"
-           transform="translate(177.85715,2.8571441)"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           id="path3913"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
-      <g
-         id="g3915">
-        <path
-           ns0:duplicate-src="path3105-0"
-           transform="translate(177.85715,2.8571441)"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           id="path3917"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
-      <g
-         id="g3919">
-        <path
-           ns0:duplicate-src="path3105-0"
-           transform="translate(177.85715,2.8571441)"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           id="path3921"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
+       id="g3683">
       <g
-         id="g3931">
-        <path
-           ns0:duplicate-src="path3105-0"
-           transform="translate(177.85715,2.8571441)"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           id="path3933"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
-      <g
-         id="g3935">
-        <path
-           ns0:duplicate-src="path3105-0"
-           transform="translate(177.85715,2.8571441)"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           id="path3937"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
-      <g
-         id="g3947">
-        <path
-           ns0:duplicate-src="path3105-0"
-           transform="translate(177.85715,2.8571441)"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           id="path3949"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
-      <g
-         id="g3951">
-        <path
-           ns0:duplicate-src="path3105-0"
-           transform="translate(177.85715,2.8571441)"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           id="path3953"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
-      <g
-         id="g3963">
-        <path
-           ns0:duplicate-src="path3105-0"
-           transform="translate(177.85715,2.8571441)"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           id="path3965"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
-      <g
-         id="g3967">
-        <path
-           ns0:duplicate-src="path3105-0"
-           transform="translate(177.85715,2.8571441)"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           id="path3969"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
-      <g
-         id="g3979">
+         ref="path3196"
+         id="g3685"
+         transform="matrix(1,0,0,1,0,51.4286)">
         <path
            ns0:duplicate-src="path3105-0"
            transform="translate(177.85715,2.8571441)"
            sodipodi:type="arc"
            style="fill:#999999;fill-opacity:1;display:inline"
-           id="path3981"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
-      <g
-         id="g3983">
-        <path
-           ns0:duplicate-src="path3105-0"
-           transform="translate(177.85715,2.8571441)"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           id="path3985"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
-      <g
-         id="g3987">
-        <path
-           ns0:duplicate-src="path3105-0"
-           transform="translate(177.85715,2.8571441)"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           id="path3989"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
-      <g
-         id="g3991">
-        <path
-           ns0:duplicate-src="path3105-0"
-           transform="translate(177.85715,2.8571441)"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           id="path3993"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
-      <g
-         id="g3995">
-        <path
-           ns0:duplicate-src="path3105-0"
-           transform="translate(177.85715,2.8571441)"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           id="path3997"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
-      <g
-         id="g3999">
-        <path
-           ns0:duplicate-src="path3105-0"
-           transform="translate(177.85715,2.8571441)"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           id="path4001"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
-      <g
-         id="g4003">
-        <path
-           ns0:duplicate-src="path3105-0"
-           transform="translate(177.85715,2.8571441)"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           id="path4005"
+           id="path3687"
            sodipodi:cx="73.571426"
            sodipodi:cy="46.647896"
            sodipodi:rx="29.285715"
            sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
-      <g
-         id="g4007">
-        <path
-           ns0:duplicate-src="path3105-0"
-           transform="translate(177.85715,2.8571441)"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           id="path4009"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
-      <g
-         id="g4011">
-        <path
-           ns0:duplicate-src="path3105-0"
-           transform="translate(177.85715,2.8571441)"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           id="path4013"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
-      <g
-         id="g4015">
-        <path
-           ns0:duplicate-src="path3105-0"
-           transform="translate(177.85715,2.8571441)"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           id="path4017"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
-      <g
-         id="g4019">
-        <path
-           ns0:duplicate-src="path3105-0"
-           transform="translate(177.85715,2.8571441)"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           id="path4021"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
-      <g
-         id="g4023">
-        <path
-           ns0:duplicate-src="path3105-0"
-           transform="translate(177.85715,2.8571441)"
-           sodipodi:type="arc"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           id="path4025"
-           sodipodi:cx="73.571426"
-           sodipodi:cy="46.647896"
-           sodipodi:rx="29.285715"
-           sodipodi:ry="28.571428"
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           ref="path3196" />
-      </g>
-      <g
-         ref="path3105-0"
-         id="g4027"
-         transform="matrix(1,0,0,1,0,0)">
-        <path
-           d="m 102.85714,46.647896 a 29.285715,28.571428 0 1 1 -58.571429,0 29.285715,28.571428 0 1 1 58.571429,0 z"
-           sodipodi:ry="28.571428"
-           sodipodi:rx="29.285715"
-           sodipodi:cy="46.647896"
-           sodipodi:cx="73.571426"
-           id="path4029"
-           style="fill:#999999;fill-opacity:1;display:inline"
-           sodipodi:type="arc"
-           transform="translate(177.85715,2.8571441)" />
+           d="m 102.85714,46.647896 c 0,15.779564 -13.11166,28.571428 -29.285714,28.571428 -16.174053,0 -29.285715,-12.791864 -29.285715,-28.571428 0,-15.779564 13.111662,-28.571428 29.285715,-28.571428 16.174054,0 29.285714,12.791864 29.285714,28.571428 z" />
       </g>
     </g>
   </g>
--- a/pyink/tween.py	Mon Dec 27 23:20:13 2010 +0800
+++ b/pyink/tween.py	Tue Dec 28 22:26:11 2010 +0800
@@ -62,6 +62,14 @@
 	    node = node.next()
 	    pass
 
+	# Remove duplicate nodes that is not in the set of stop nodes
+	for node_ref in dup_nodes:
+	    if node_ref not in stop_nodes:
+		node = dup_nodes[node_ref]
+		duplicate_group.removeChild(node)
+		pass
+	    pass
+
 	#
 	# Node ID of a node of start scene must be mapped to
 	# 'ns0:duplicate-src' attribute of a node of stop scene.  The
@@ -75,6 +83,7 @@
 	start_node = start_scene_group.firstChild()
 	while start_node:
 	    start_node_id = start_node.getAttribute('id')
+	    dup_node = dup_nodes.setdefault(start_node_id, None)
 	    try:
 		stop_node = stop_nodes[start_node_id]
 	    except KeyError:
@@ -84,7 +93,6 @@
 		start_node = start_node.next()
 		continue
 	    
-	    dup_node = dup_nodes.setdefault(start_node_id, None)
 	    
 	    self.updateTweenObject(duplicate_group, tween_type,
 				   start_node, stop_node,