smartComponentPollMapping doesn't work well


#1

Hi Glyphs team,

I really like the concept of the smart component for CKJ, so I’m trying to make some scripts for that. But there are some problems while using smartComponentPollMapping.

I wanted to change the axis values of smart components by setting smartComponentPollMapping attribute. But it didn’t work well. So I’ve consumed a lot of time that I found out that it needs ‘userData - PartSelection’ by comparing two glyphs files that the one is from changing by GUI and the one is from changing by the script. But the glyphs file from GUI contains userData, but the one from the script does not contain it.

So, I put ‘userData’ like below.

	for layer in smartGlyph.layers:
		userData = {}
		if layer.name == 'Regular':
			for axis in smart.layers:
				if axis.name != 'Regular':
					userData[axis.name] = 2
		else:
			userData = { layer.name: 2}

		layer.userData['PartSelection'] = userData

		for axis in smart.layers:
			if layer.name == 'Regular':
				layer.smartComponentPoleMapping[axis.name] = 2

			if axis.name == layer.name:
				layer.smartComponentPoleMapping[axis.name] = 1

But I found out another problem which is the code above does not work on running state. But if saving and reopening Glyphs again, I could figure out it works well. I want it to be effective while running Glyphs app.

I hope it to be fixed soon.

Thanks.


#2

I have a look at this. That the PartSelection is stored in the usedData is an implementation detail and you should not use that. Because at runtime, that value is not taken from the userdata but from the smartComponentPoleMapping.

I need to understand what you are trying to do. Could you send me that font that I can try it for myself?


#3

The codes that posted have some problems so you could not understand well.
My goals by scripting are like these.

  1. Set the properties of the smart component programmatically

  2. Set the layer value of each property of the smart component programmatically

  3. Set the smart component value programmatically

So I put the script to achieve the goals.

# setting pole value for smart glyph
smartGlyph = Glyphs.font.glyphs['_part.stick1']
axis = GSSmartComponentAxis()
axis.setName_('Angle')
axis.topValue = 1000
axis.bottomValue = 0
smartGlyph.smartComponentAxes.append(axis)	

for layer in smartGlyph.layers:
	if layer.name == 'Regular':
		layer.smartComponentPoleMapping[axis.name] = 2
	if axis.name == layer.name:
		layer.smartComponentPoleMapping[axis.name] = 1

# setting glyphs for axis value of smart component
glyph = Glyphs.font.glyphs['test_ma-ko']
component = glyph.layers[0].components[0]
component.smartComponentValues['Angle'] = 350

I expect the ‘test_ma-ko’ glyphs might be transformed by the changed Angle value, but it did not happen.

This is sample glyph file. sample.glyphs


#4

You are almost there. The mapping uses an ID, not the name.

layer.smartComponentPoleMapping[axis.id()] = 2

I’ll update the documentation accordingly.


#5

And Glyphs is playing a trick on you, too. After saving and opening the file, the id and the name are the same. But not for newly created axes.


#6

Thanks Georg, it does work. And ‘smartComponentValues’ requires axis.id() as well to change values directly while running Glyphs App.

component.smartComponentValues[axis.id()] = 350


#7

When I’m on it, I’ll add the .id to the wrapper. So in the next version, you need to remove the parentheses after the .id.


#8

This tip is very helpful, thanks.