Can't Parent NURBS Curves with Transformations

Hi,
I have a script that combines NURBS curves. Curves with transforms, however won’t freeze their transformations before parenting.

For example, I create two NURBS curves. I scale one down. I select the outer Curve (with no scale), then the inner Curve with a scale transformation.

Then I run this script.


import pymel.core as pm

#creating a list of the selected Curves' transforms
transforms = pm.ls( selection=True, type="transform")

#freezing transformations on all Curves transforms
pm.makeIdentity( apply=True, translate=1, rotate=1, scale=1 )

#seems to have worked at this point...
for x in transforms:
    print (x.getTranslation(),x.getRotation(),x.getScale())
#(dt.Vector([0.0, 0.0, 0.0]), dt.EulerRotation([0.0, 0.0, 0.0]), [1.0, 1.0, 1.0])
#(dt.Vector([0.0, 0.0, 0.0]), dt.EulerRotation([0.0, 0.0, 0.0]), [1.0, 1.0, 1.0])

#selecting the shapes within the Curves transforms
pm.pickWalk( type='nodes', direction='down')

#creating a list of the shapes
shapes = pm.ls( selection = True )

#reselecting the transforms
pm.select( transforms )

#removing the first shape from the list so it doesn't get parented to its own transform
shapes.pop(0)

#selecting the shapes list
pm.select( shapes )

#selecting the first transform last so it will be the parent transform
pm.select( transforms[0], add=True )

#parenting the selected shapes to the selected transform
pm.parent( relative=True, shape=True )


For some reason, the makeIdentity (AKA Freeze Transformations) doesn’t happen before the parenting and any NURBS curve with a transform, rotation, or scale selected AFTER a curve with a different transform gets resized.

If I freeze transformations, then run this script, it works correctly.

How can I make sure that makeIdentity has been run before I run the parent command? Thank you!

Hello,

My advice would be to grab some beginner tutorials in python on youtube to learn about control flow and other things in python.
Tutorials doesn’t need to be related to Maya when you start learning, it can be easier to grasp python fundamentals and then apply it to Maya.

Pymel offers a lot of convenience methods, so if you intend to use it that’s where the “power” is for the most part.

Here a simple solution.
Not sure why you want to freeze transform the transforms in the first place.
It could be done in differents ways, i make it very simple.

Note that it will work only with transform that have only one shape. (it will take the first shape found under the transform)
If you want to make it work with transforms with multiple shapes you can use the object.getShapes() method. (note the “s” at the end)
Try to make it as an exercise if you want.

import pymel.core as pmc

# get the selection where the first curve selected is the one we want to keep the transform. Return a list of transform.
curves = pmc.selected()

# freeze the transform for each curve (in case you done something to them)
for curve in curves:
    pmc.makeIdentity(apply=True, translate=1, rotate=1, scale=1)

# for each curve except the first one:
# get the shape, freeze transform it,  parent it under the first curve and finally delete the remaining empty transform
for curve in curves[1:]:
    shape = curve.getShape()
    pmc.makeIdentity(shape, apply=True, translate=1, rotate=1, scale=1)
    pmc.parent(shape, curves[0], relative=True, shape=True)
    pmc.delete(curve)



Thanks Sam.

This doesn’t work for me.

//youtu.be/6RYxigD9Kyc

Hey,

it should work :

  • Shift select the curves in order in the scene or in the outliner, don’t drag select as it seems you’re doing. (select the first curve then shift select the second, then third)
  • Run the first for loop
  • run the second for loop

use the following code as i forgot one parameter

import pymel.core as pmc

# get the selection where the first curve selected is the one we want to keep the transform. Return a list of transform.
curves = pmc.selected()

# freeze the transform for each curve (in case you done something to them)
for curve in curves:
    pmc.makeIdentity(curve, apply=True, translate=1, rotate=1, scale=1)

# for each curve except the first one:
# get the shape, freeze transform it,  parent it under the first curve and finally delete the remaining empty transform
for curve in curves[1:]:
    shape = curve.getShape()
    pmc.makeIdentity(shape, apply=True, translate=1, rotate=1, scale=1)
    pmc.parent(shape, curves[0], relative=True, shape=True)
    pmc.delete(curve)

[QUOTE=-Sam-;30742]Hey,
it should work :

  • Shift select the curves in order in the scene or in the outliner, don’t drag select as it seems you’re doing. (select the first curve then shift select the second, then third)
  • Run the first for loop
  • run the second for loop

use the following code as i forgot one parameter
[/QUOTE]

Hi Sam,
I am sorry, but this code does not work when I select the curves individually.

//youtu.be/SR1ZbTlRexI

you need to run separatly each for loop to make it work with the actual code.
I’ve break it that way to make it more easy to dissect.
To make it run on one go, you can parent the transform of the child curve to the parent one, freeze transform it, then parent the shape.