Merge pull request #1283 from zhujun98/fix_array_to_qpath
Fix arrayToPath
This commit is contained in:
commit
b79c979663
@ -1471,12 +1471,14 @@ def arrayToQPath(x, y, connect='all'):
|
|||||||
|
|
||||||
## Speed this up using >> operator
|
## Speed this up using >> operator
|
||||||
## Format is:
|
## Format is:
|
||||||
## numVerts(i4) 0(i4)
|
## numVerts(i4)
|
||||||
## x(f8) y(f8) 0(i4) <-- 0 means this vertex does not connect
|
## 0(i4) x(f8) y(f8) <-- 0 means this vertex does not connect
|
||||||
## x(f8) y(f8) 1(i4) <-- 1 means this vertex connects to the previous vertex
|
## 1(i4) x(f8) y(f8) <-- 1 means this vertex connects to the previous vertex
|
||||||
## ...
|
## ...
|
||||||
## 0(i4)
|
## cStart(i4) fillRule(i4)
|
||||||
##
|
##
|
||||||
|
## see: https://github.com/qt/qtbase/blob/dev/src/gui/painting/qpainterpath.cpp
|
||||||
|
|
||||||
## All values are big endian--pack using struct.pack('>d') or struct.pack('>i')
|
## All values are big endian--pack using struct.pack('>d') or struct.pack('>i')
|
||||||
|
|
||||||
path = QtGui.QPainterPath()
|
path = QtGui.QPainterPath()
|
||||||
@ -1484,12 +1486,12 @@ def arrayToQPath(x, y, connect='all'):
|
|||||||
#profiler = debug.Profiler()
|
#profiler = debug.Profiler()
|
||||||
n = x.shape[0]
|
n = x.shape[0]
|
||||||
# create empty array, pad with extra space on either end
|
# create empty array, pad with extra space on either end
|
||||||
arr = np.empty(n+2, dtype=[('x', '>f8'), ('y', '>f8'), ('c', '>i4')])
|
arr = np.empty(n+2, dtype=[('c', '>i4'), ('x', '>f8'), ('y', '>f8')])
|
||||||
# write first two integers
|
# write first two integers
|
||||||
#profiler('allocate empty')
|
#profiler('allocate empty')
|
||||||
byteview = arr.view(dtype=np.ubyte)
|
byteview = arr.view(dtype=np.ubyte)
|
||||||
byteview[:12] = 0
|
byteview[:16] = 0
|
||||||
byteview.data[12:20] = struct.pack('>ii', n, 0)
|
byteview.data[16:20] = struct.pack('>i', n)
|
||||||
#profiler('pack header')
|
#profiler('pack header')
|
||||||
# Fill array with vertex values
|
# Fill array with vertex values
|
||||||
arr[1:-1]['x'] = x
|
arr[1:-1]['x'] = x
|
||||||
@ -1499,26 +1501,31 @@ def arrayToQPath(x, y, connect='all'):
|
|||||||
if eq(connect, 'all'):
|
if eq(connect, 'all'):
|
||||||
arr[1:-1]['c'] = 1
|
arr[1:-1]['c'] = 1
|
||||||
elif eq(connect, 'pairs'):
|
elif eq(connect, 'pairs'):
|
||||||
arr[1:-1]['c'][::2] = 1
|
arr[1:-1]['c'][::2] = 0
|
||||||
arr[1:-1]['c'][1::2] = 0
|
arr[1:-1]['c'][1::2] = 1 # connect every 2nd point to every 1st one
|
||||||
elif eq(connect, 'finite'):
|
elif eq(connect, 'finite'):
|
||||||
arr[1:-1]['c'] = np.isfinite(x) & np.isfinite(y)
|
# Let's call a point with either x or y being nan is an invalid point.
|
||||||
|
# A point will anyway not connect to an invalid point regardless of the
|
||||||
|
# 'c' value of the invalid point. Therefore, we should set 'c' to 0 for
|
||||||
|
# the next point of an invalid point.
|
||||||
|
arr[2:]['c'] = np.isfinite(x) & np.isfinite(y)
|
||||||
elif isinstance(connect, np.ndarray):
|
elif isinstance(connect, np.ndarray):
|
||||||
arr[1:-1]['c'] = connect
|
arr[1:-1]['c'] = connect
|
||||||
else:
|
else:
|
||||||
raise Exception('connect argument must be "all", "pairs", "finite", or array')
|
raise Exception('connect argument must be "all", "pairs", "finite", or array')
|
||||||
|
|
||||||
|
arr[1]['c'] = 0 # the first vertex has no previous vertex to connect
|
||||||
|
|
||||||
#profiler('fill array')
|
#profiler('fill array')
|
||||||
# write last 0
|
byteview.data[-20:-16] = struct.pack('>i', 0) # cStart
|
||||||
lastInd = 20*(n+1)
|
byteview.data[-16:-12] = struct.pack('>i', 0) # fillRule (Qt.OddEvenFill)
|
||||||
byteview.data[lastInd:lastInd+4] = struct.pack('>i', 0)
|
|
||||||
#profiler('footer')
|
#profiler('footer')
|
||||||
# create datastream object and stream into path
|
# create datastream object and stream into path
|
||||||
|
|
||||||
## Avoiding this method because QByteArray(str) leaks memory in PySide
|
## Avoiding this method because QByteArray(str) leaks memory in PySide
|
||||||
#buf = QtCore.QByteArray(arr.data[12:lastInd+4]) # I think one unnecessary copy happens here
|
#buf = QtCore.QByteArray(arr.data[12:lastInd+4]) # I think one unnecessary copy happens here
|
||||||
|
|
||||||
path.strn = byteview.data[12:lastInd+4] # make sure data doesn't run away
|
path.strn = byteview.data[16:-12] # make sure data doesn't run away
|
||||||
try:
|
try:
|
||||||
buf = QtCore.QByteArray.fromRawData(path.strn)
|
buf = QtCore.QByteArray.fromRawData(path.strn)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user