Swift - Can't Reach SCNMorpher Target by Name

I'm building an ARKit app using SceneKit. I have a 3D model in a

.dae
file that has 3 SCNMorpher targets (namely blendShapes). They are all attributes of a node called
rightEyeBrow
.


The .dae file was exported from Blender. I opened the .dae file using a text editor and replaced "instance_geometry" entry with "instance_controller" for this node. If you would like to know why I did that please check out this post.


Here's a list of morph targets as viewed on Xcode's SceneKit editor.


I can list the array of targets of the node simply by printing them to the console line.

print(rightEyeBrow.morpher?.targets)


What I need to do now is to set a certain weight to one of the morpher's targets:


rightEyeBrow.morpher?.setWeight(browInnerUp, forTargetNamed: "browInnerUp"

For some reason this approach doesn't work. It appears XCode can't find targets named "browDownRight", "browOuterUpRight" and "browInnerUp". However, they are listed in the array of targets at index 0, 1 and 2. For instance, I can easily do it this way:


rightEyeBrow.morpher?.setWeight(browInnerUp, forTargetAt: 2)

This works, but when there are lots of morpher targets it gets really confusing to reach them by their index. Would anybody know why reaching the target by it's name doesn't work?


Note: When I try to reach the target by its name, it doesn't work, but doesn't throw any kind of error. A similar question was asked here.

Accepted Reply

If you convert your .dae to a .scn the targets should be named correctly.

Replies

Hello,


I am unable to reproduce this issue, are you certain that the target geometry's name is "browInnerUp", and not "browInnerUp " with some trailing whitespace?


Try using the name exactly as is from the morpher targets, i.e.:


let firstName = rightEyeBrow.morpher?.targets[0].name


then pass firstName to the setWeight(_:forTargetNamed:) method as a test, if this still fails then please file a bug report at https://developer.apple.com/bug-reporting/

Hi gchiste,


Unfortunately, this doesnt work. When I try:


let firstName = rightEyeBrow.morpher?.targets[0].name
print(firstName)


The output is nil.


I checked my naming as well and even tried adding a trailing whitespace, but I received no positive result.


Have you tried exporting a .dae file with shapekeys from blender, opening that file using a text editor, changing instance_geometry" entry with "instance_controller" for the shapekeyed node, importing the updated .dae file into XCode and ran the project? I just want to make sure you followed the same path I did when trying to replicate the results I received.


I filed a bug report with as well.


Thanks,

Deger

The fact that your target geometry's names are all nil means that you won't be able to use setWeight(_:forTargetNamed:). You need to set the names of the target geometries.

I understand that the names are nil and they need to be set to in order for me to use setWeight(_:forTargetNamed:).


Can you clarify one thing for me, SceneKit and 3D design are new to me. I believe the morph targets listed on SceneKit's XCode editor are are geometries, aren't they? If so, according to the editor all morph target geometries have names, as you can see here. If my understanding is correct, can you please explain why I see the names on the editor, but can't view/access them through code?


How can I set the names from my imported model?

The names of the target geometries are not automatically set on imported models. You can set them yourself by iterating through the targets and setting the 'name' property on each target. If you would like to see the targets be automatically named on imported models, please file an enhancement request at https://developer.apple.com/bug-reporting/

For instance let's assume I have a node called eyebrowRight. It has 3 geometry morphers (browInnerUp, browDownRight, browOuterRight) attached to it. The names of target geometries are visible on the visual editor.


So, based on what you said, can't I view/list the name of target geometries? If I can how?


I'm looking for a way to assign target geometry names in a loop. Right now it seems like I would need to open the Scenekit visual editor, select a node with morpher geometries, and manually assign each listed morph target name in order like so:


eyebrowRight.morpher?.targets[0].name = "browInnerUp"
eyebrowRight.morpher?.targets[1].name = "browDownRight"
eyebrowRight.morpher?.targets[2].name = "browOuterRight"


This is will take time and it won't be flexible because values will be hard coded.


Is there a way to list all names and assign them to morph geometries in a loop?

If you convert your .dae to a .scn the targets should be named correctly.

Hi, this solves all of the problems I face.


Is there a way to convert optimized .dae files to .scn files at runtime within an iOS app?