21
21
# relationships
22
22
23
23
class TransformNode (object ):
24
+ _gid = 0
25
+
24
26
def __init__ (self ):
25
- self ._parents = Set ()
26
- self ._children = []
27
+ self ._parents = WeakKeyDictionary ()
28
+ self ._children = Set ()
29
+ self ._id = TransformNode ._gid
27
30
28
- def invalidate (self , which_child = None , affine_only = []):
29
- if which_child is None :
30
- which_child = self
31
- self ._do_invalidation (which_child , affine_only )
32
- # affine_only = affine_only and (self.is_affine() or self.is_bbox())
33
- for parent in self ._parents :
34
- parent .invalidate (self , affine_only + [self ])
35
-
36
- def _do_invalidation (self , which_child , affine_only ):
37
- pass
31
+ def invalidate (self , affine_only = None ):
32
+ if affine_only is None :
33
+ affine_only = self .is_affine () or self .is_bbox ()
34
+ if not self ._do_invalidation (affine_only ):
35
+ self ._id = TransformNode ._gid
36
+ TransformNode ._gid += 1
37
+ for parent in self ._parents .iterkeys ():
38
+ parent .invalidate (affine_only )
39
+
40
+ def _do_invalidation (self , affine_only ):
41
+ return False
38
42
39
43
def set_children (self , children ):
40
44
for child in children :
41
- getattr (self , child )._parents . add ( self )
45
+ getattr (self , child )._parents [ self ] = None
42
46
self ._children = children
43
47
44
48
def make_graphviz (self , fobj ):
@@ -74,6 +78,9 @@ def is_affine(self):
74
78
def is_bbox (self ):
75
79
return False
76
80
81
+ def get_id (self ):
82
+ return self ._id
83
+
77
84
78
85
class BboxBase (TransformNode ):
79
86
'''
@@ -214,6 +221,7 @@ class Bbox(BboxBase):
214
221
def __init__ (self , points ):
215
222
BboxBase .__init__ (self )
216
223
self ._points = npy .asarray (points , npy .float_ )
224
+ self ._invalid = False
217
225
218
226
#@staticmethod
219
227
def unit ():
@@ -235,6 +243,11 @@ def __repr__(self):
235
243
return 'Bbox(%s)' % repr (self ._points )
236
244
__str__ = __repr__
237
245
246
+ def _do_invalidation (self , affine_only ):
247
+ result = self ._invalid
248
+ self ._invalid = True
249
+ return result
250
+
238
251
def update_from_data (self , x , y , ignore = True ):
239
252
if ignore :
240
253
self ._points = npy .array (
@@ -294,6 +307,7 @@ def _set_bounds(self, bounds):
294
307
bounds = property (BboxBase ._get_bounds , _set_bounds )
295
308
296
309
def get_points (self ):
310
+ self ._invalid = False
297
311
return self ._points
298
312
299
313
def set_points (self , points ):
@@ -348,21 +362,23 @@ def __init__(self, bbox, transform):
348
362
assert transform .output_dims == 2
349
363
350
364
BboxBase .__init__ (self )
351
- self .bbox = bbox
352
- self .transform = transform
353
- self .set_children (['bbox ' , 'transform ' ])
365
+ self ._bbox = bbox
366
+ self ._transform = transform
367
+ self .set_children (['_bbox ' , '_transform ' ])
354
368
self ._points = None
355
369
356
370
def __repr__ (self ):
357
- return "TransformedBbox(%s, %s)" % (self .bbox , self .transform )
371
+ return "TransformedBbox(%s, %s)" % (self ._bbox , self ._transform )
358
372
__str__ = __repr__
359
373
360
- def _do_invalidation (self , which_child , affine_only ):
374
+ def _do_invalidation (self , affine_only ):
375
+ result = self ._points is None
361
376
self ._points = None
377
+ return result
362
378
363
379
def get_points (self ):
364
380
if self ._points is None :
365
- self ._points = self .transform .transform (self .bbox .get_points ())
381
+ self ._points = self ._transform .transform (self ._bbox .get_points ())
366
382
return self ._points
367
383
368
384
@@ -461,9 +477,6 @@ def is_affine(self):
461
477
def __array__ (self , * args , ** kwargs ):
462
478
return self .get_matrix ()
463
479
464
- def _do_invalidation (self , which_child , affine_only ):
465
- self ._inverted = None
466
-
467
480
#@staticmethod
468
481
def _concat (a , b ):
469
482
return npy .dot (b , a )
@@ -477,9 +490,6 @@ def concat(a, b):
477
490
def get_matrix (self ):
478
491
raise NotImplementedError ()
479
492
480
- def transform_affine (self , points ):
481
- return self .transform (points )
482
-
483
493
def transform_non_affine (self , points ):
484
494
return points
485
495
@@ -528,9 +538,11 @@ def transform(self, values):
528
538
# print "".join(traceback.format_stack())
529
539
# print points
530
540
mtx = self .get_matrix ()
531
- points = ma .asarray (values , npy .float_ )
541
+ points = npy .asarray (values , npy .float_ )
532
542
return points * mtx [0 ,0 ] + mtx [0 ,1 ]
533
543
544
+ transform_affine = transform
545
+
534
546
def inverted (self ):
535
547
if self ._inverted is None :
536
548
mtx = self .get_matrix ()
@@ -575,7 +587,7 @@ def get_matrix(self):
575
587
def set_matrix (self , mtx ):
576
588
self ._mtx = mtx
577
589
self .invalidate ()
578
-
590
+
579
591
def set (self , other ):
580
592
self ._mtx = other .get_matrix ()
581
593
self .invalidate ()
@@ -620,9 +632,11 @@ def __repr__(self):
620
632
return "IntervalTransform(%s)" % (getattr (self ._bbox , self ._direction ))
621
633
__str__ = __repr__
622
634
623
- def _do_invalidation (self , which_child , affine_only ):
635
+ def _do_invalidation (self , affine_only ):
636
+ result = self ._mtx is None
624
637
self ._mtx = None
625
- Affine1DBase ._do_invalidation (self , which_child , affine_only )
638
+ self ._inverted = None
639
+ return result
626
640
627
641
def get_matrix (self ):
628
642
if self ._mtx is None :
@@ -678,12 +692,14 @@ def transform(self, points):
678
692
# print "".join(traceback.format_stack())
679
693
# print points
680
694
mtx = self .get_matrix ()
681
- points = ma .asarray (points , npy .float_ )
695
+ points = npy .asarray (points , npy .float_ )
682
696
points = points .transpose ()
683
- points = ma .dot (mtx [0 :2 , 0 :2 ], points )
697
+ points = npy .dot (mtx [0 :2 , 0 :2 ], points )
684
698
points = points + mtx [0 :2 , 2 :]
685
699
return points .transpose ()
686
700
701
+ transform_affine = transform
702
+
687
703
def inverted (self ):
688
704
if self ._inverted is None :
689
705
mtx = self .get_matrix ()
@@ -801,19 +817,12 @@ def get_matrix(self):
801
817
802
818
def transform (self , points ):
803
819
return points
804
-
805
- def transform_affine (self , points ):
806
- return points
807
-
808
- def transform_non_affine (self , points ):
809
- return points
820
+ transform_affine = transform_non_affine = transform
810
821
811
822
def get_affine (self ):
812
823
return self
824
+ inverted = get_affine
813
825
814
- def inverted (self ):
815
- return self
816
-
817
826
818
827
class BlendedGenericTransform (Transform ):
819
828
input_dims = 2
@@ -857,14 +866,12 @@ def transform(self, points):
857
866
y_points = y .transform (points [:, 1 ])
858
867
y_points = y_points .reshape ((len (y_points ), 1 ))
859
868
860
- return ma .concatenate ((x_points , y_points ), 1 )
861
-
869
+ return npy .concatenate ((x_points , y_points ), 1 )
870
+ transform_non_affine = transform
871
+
862
872
def transform_affine (self , points ):
863
873
return points
864
874
865
- def transform_non_affine (self , points ):
866
- return self .transform (points )
867
-
868
875
def get_affine (self ):
869
876
return IdentityTransform ()
870
877
@@ -892,9 +899,10 @@ def __repr__(self):
892
899
return "BlendedAffine1D(%s,%s)" % (self ._x , self ._y )
893
900
__str__ = __repr__
894
901
895
- def _do_invalidation (self , which_child , affine_only ):
902
+ def _do_invalidation (self , affine_only ):
903
+ result = self ._mtx is None
896
904
self ._mtx = None
897
- Affine2DBase . _do_invalidation ( self , which_child , affine_only )
905
+ self . _inverted = None
898
906
899
907
def get_matrix (self ):
900
908
if self ._mtx is None :
@@ -928,9 +936,11 @@ def __repr__(self):
928
936
return "BlendedAffine2D(%s,%s)" % (self ._x , self ._y )
929
937
__str__ = __repr__
930
938
931
- def _do_invalidation (self , which_child , affine_only ):
939
+ def _do_invalidation (self , affine_only ):
940
+ result = self ._mtx is None
932
941
self ._mtx = None
933
- Affine2DBase ._do_invalidation (self , which_child , affine_only )
942
+ self ._inverted = None
943
+ return result
934
944
935
945
def get_matrix (self ):
936
946
if self ._mtx is None :
@@ -985,7 +995,7 @@ def transform_non_affine(self, points):
985
995
return self ._b .transform_non_affine (self ._a .transform_non_affine (points ))
986
996
987
997
def get_affine (self ):
988
- return self ._a .get_affine () + self ._b .get_affine ()
998
+ return CompositeAffine2D ( self ._a .get_affine (), self ._b .get_affine () )
989
999
990
1000
def inverted (self ):
991
1001
return CompositeGenericTransform (self ._b .inverted (), self ._a .inverted ())
@@ -1009,9 +1019,11 @@ def __repr__(self):
1009
1019
return "CompositeAffine2D(%s, %s)" % (self ._a , self ._b )
1010
1020
__str__ = __repr__
1011
1021
1012
- def _do_invalidation (self , which_child , affine_only ):
1022
+ def _do_invalidation (self , affine_only ):
1023
+ result = self ._mtx is None
1013
1024
self ._mtx = None
1014
- Affine2DBase ._do_invalidation (self , which_child , affine_only )
1025
+ self ._inverted = None
1026
+ return result
1015
1027
1016
1028
def get_matrix (self ):
1017
1029
if self ._mtx is None :
@@ -1117,10 +1129,12 @@ def __repr__(self):
1117
1129
return "BboxTransform(%s, %s)" % (self ._boxin , self ._boxout )
1118
1130
__str__ = __repr__
1119
1131
1120
- def _do_invalidation (self , which_child , affine_only ):
1132
+ def _do_invalidation (self , affine_only ):
1133
+ result = self ._mtx is None
1121
1134
self ._mtx = None
1122
- Affine2DBase ._do_invalidation (self , which_child , affine_only )
1123
-
1135
+ self ._inverted = None
1136
+ return result
1137
+
1124
1138
def is_separable (self ):
1125
1139
return True
1126
1140
@@ -1148,21 +1162,19 @@ def __init__(self, path, transform):
1148
1162
1149
1163
self ._path = path
1150
1164
self ._transform = transform
1151
- self .set_children (['_transform' ])
1152
1165
self ._transformed_path = None
1166
+ self ._last_id = transform .get_id ()
1153
1167
1154
- def _do_invalidation (self , which_child , affine_only ):
1155
- if not (affine_only [0 ].is_affine () or affine_only [0 ].is_bbox ()):
1156
- self ._transformed_path = None
1157
-
1158
1168
def get_path_and_affine (self ):
1159
- if self ._transformed_path is None :
1169
+ if (self ._transformed_path is None or
1170
+ self ._last_id != self ._transform .get_id ()):
1160
1171
vertices = self ._transform .transform_non_affine (self ._path .vertices )
1161
1172
self ._transformed_path = Path (vertices , self ._path .codes )
1162
1173
return self ._transformed_path , self ._transform .get_affine ()
1163
1174
1164
1175
def get_path (self ):
1165
- if self ._transformed_path is None :
1176
+ if (self ._transformed_path is None or
1177
+ self ._last_id != self ._transform .get_id ()):
1166
1178
vertices = self ._tranform .transform_non_affine (self ._path .vertices )
1167
1179
self ._transformed_path = Path (vertices , self ._path .codes )
1168
1180
vertices = self ._transform .transform_affine (self ._transformed_path .vertices )
0 commit comments