Reporter, highlighting segments


#1

I’m trying to write a reporter plugin which highlights alternating segments (e.g. segments 0, 2, 4… are drawn in green). I can get path.segments, and each segment I get is an array of NSPoints. My problem is that I cannot get its bezierPath easily. I have a following function that’s supposed to return NSPath of the given segment.

def segPath(nodes):
	np = NSBezierPath.alloc().init()
	np.moveToPoint_(nodes[0])
	if len(nodes) == 2: # straight line
		np.lineToPoint_(nodes[1])
	elif len(nodes) == 4: # curve
		np.curveToPoint_controlPoint1_controlPoint2_(nodes[3], nodes[1], nodes[2])
	np.closePath()
	return np

However, I get this error where I do moveToPoint : TypeError: depythonifying struct, got no sequence

What am I doing wrong? Or is there a better way? I personally think paths.segments can be packaged differently. Just an array of NSPoints doesn’t seem all that helpful.


#2

The segments are Immutable NSArrays, you can iterate through them, no problem. But the points contained in them are neither GSNodes nor NSPoints. You need to convert them to NSPoints first, see the last line:

for p in Layer.paths:
	for s in p.segments:
		print "Segment:"
		for p in s:
			print p.pointValue()		

Or into GSNodes with GSNode(p.pointValue()) or specify its type GSNode(p.pointValue(), CURVE), or GSNode(p.pointValue(), OFFCURVE) or GSNode(p.pointValue(), LINE).


#3

this should work:

def segPath(nodes):
	np = NSBezierPath.alloc().init()
	np.moveToPoint_(nodes[0].pointValue())
	if len(nodes) == 2: # straight line
		np.lineToPoint_(nodes[1].pointValue())
	elif len(nodes) == 4: # curve
		np.curveToPoint_controlPoint1_controlPoint2_(nodes[3].pointValue(), nodes[1].pointValue(), nodes[2].pointValue())
	return np

(add the .pointValue() and removed the np.closePath())


#4

Thanks guys, I discovered independently that I needed to re-package the coordinates in a new NSPoint, like Rainer suggested. I thought it was already NSPoint, because when you print each node in a segment, it says NSPoint: {x, y}.

I also noticed that closePath() adds an unnecessary line. Thanks Georg.


#5

nodes is an NSArray and it can only contain objects. NSPoint is a struct (a low level c data structure). To put the NSPoint into the array, you need to wrap it in an NSValue object. And to get to the actual coordinates, you need to ask it for it with pointValue(). This sounds complicated. Python is doing that all the time internally because it only has objects and needs to unpack and repack then all the time when you do simple math and stuff. That is the main performance difference between python and ObjectiveC. And as long as you store your stuff in an NSArray, python and ObjectiveC are similarly slow.