Home Website Youtube GitHub

Ghost structure Post step script error

I am using the same script that appears in the facial rigging workshop. I follow the steps in the video to the letter, but an unexpected error appears and I don’t understand why it happens.

Especially in this line of code:

File "C:\Users\darwi\Documents\Mgear\Rigging\build\build facial/scripts/post/03_mouth_slide.py", line 43, in run
//     self.ghost_structure(stepDict)

19 Facial Data-Centric Rigging: 03c Mouth slide custom step

// SUCCEED: Custom Shifter Step Class: build facial/scripts/post/02_proportions.py. Succeed!!
    // EXEC: Executing custom step: build facial/scripts/post/03_mouth_slide.py
    // Interpolated Transform: mouth_C0_lipup_ctl_INTER_mouth_C0_liplow_ctl created
    // Result: rig_controllers_grp
    // Warning: mouthSlide_C0_ctl.uiHost_cnx don't have contrapart channel on mouthSlide_C0_ctl_ghost
    // Warning: mouthSlide_C0_ctl.compRoot don't have contrapart channel on mouthSlide_C0_ctl_ghost
    // Result: rig_controllers_grp
    // Result: rig_controllers_grp
    // Warning: mouthCorner_L0_ctl.uiHost_cnx don't have contrapart channel on mouthCorner_L0_ctl_ghost
    // Warning: mouthCorner_L0_ctl.compRoot don't have contrapart channel on mouthCorner_L0_ctl_ghost
    // Result: rig_controllers_grp
    // Result: rig_controllers_grp
    // Warning: mouthCorner_R0_ctl.uiHost_cnx don't have contrapart channel on mouthCorner_R0_ctl_ghost
    // Warning: mouthCorner_R0_ctl.compRoot don't have contrapart channel on mouthCorner_R0_ctl_ghost
    // Result: rig_controllers_grp
    // Error: An exception of type AttributeError occurred. 
    // Error: Traceback (most recent call last):
    //   File "C:\Users\darwi\Documents\mgear_4.2.2\release\scripts\mgear\shifter\guide.py", line 1365, in runStep
    //     cs.run(customStepDic)
    //   File "C:\Users\darwi\Documents\Mgear\Rigging\build\build facial/scripts/post/03_mouth_slide.py", line 43, in run
    //     self.ghost_structure(stepDict)
    //   File "C:\Users\darwi\Documents\Mgear\Rigging\build\build facial/scripts/post/03_mouth_slide.py", line 93, in ghost_structure
    //     stepDict["facial_base"].surface_slider,
    // AttributeError: 'CustomShifterStep' object has no attribute 'surface_slider'

tweak

Can you please share the script here too?

Here is the complete code:

'''
This custom step creates the local rig to creeate a genear sliding effect of
the mouth
'''

import os

import pymel.core as pm

import mgear.shifter.custom_step as cstp

from mgear import rigbits
from mgear.rigbits import ghost
from mgear.rigbits import blendShapes


class CustomShifterStep(cstp.customShifterMainStep):

    def __init__(self):
        self.name = "mouth_slide"

    def run(self, stepDict):
        """Run method.

            i.e:  stepDict["mgearRun"].global_ctl  gets the global_ctl from
                    shifter rig build bas
            i.e:  stepDict["mgearRun"].components["control_C0"].ctl  gets the
                    ctl from shifter component called control_C0
            i.e:  stepDict["otherCustomStepName"].ctlMesh  gets the ctlMesh
                    from a previous custom step called "otherCustomStepName"
        Arguments:
            stepDict (dict): Dictionary containing the objects from
                the previous steps

        Returns:
            None: None
        """
        self.setup_root = stepDict["facial_base"].local_setup_root(
            self, stepDict)
        self.duplicate_geo(stepDict)

        self.ghost_structure(stepDict)

        stepDict["facial_base"].import_skin(self.name)

        # After creating the mouth blendshapes, this should be connected on
        # mouth blendshapes custom step
        # NOTE: the main reason for this is that SHAPES plugin needs to create
        # a new blendshape node when import it. While  connect can add to the
        # exiting blendshape node
        # self.connect(stepDict)

    def duplicate_geo(self, stepDict):
        # Duplicate the geometry for each local rig

        self.head_geo = self.dup(stepDict["facial_base"].head_geo)

    def ghost_structure(self, stepDict):
        # creates the controls that will be exposed to the animators

        # create interpose lvl for the ctl
        intTra = rigbits.createInterpolateTransform(
            [stepDict["mgearRun"].components["mouth_C0"].lipup_ctl,
             stepDict["mgearRun"].components["mouth_C0"].liplow_ctl])
        pm.rename(intTra, intTra.name() + "_int")

        # create ghost controls
        self.mouthSlide_ctl = ghost.createGhostCtl(
            stepDict["mgearRun"].components["mouthSlide_C0"].ctl,
            intTra)
        self.cornerL_ctl = ghost.createGhostCtl(
            stepDict["mgearRun"].components["mouthCorner_L0"].ctl,
            self.mouthSlide_ctl)
        self.cornerR_ctl = ghost.createGhostCtl(
            stepDict["mgearRun"].components["mouthCorner_R0"].ctl,
            self.mouthSlide_ctl)

        # change the parent for the original controls to be under the
        # local setu root
        pm.parent(stepDict["mgearRun"].components["mouthSlide_C0"].root,
                  self.setup_root)
        pm.parent(stepDict["mgearRun"].components["mouthCorner_L0"].root,
                  stepDict["mgearRun"].components["mouthSlide_C0"].ctl)
        pm.parent(stepDict["mgearRun"].components["mouthCorner_R0"].root,
                  stepDict["mgearRun"].components["mouthSlide_C0"].ctl)

        # slide system
        ghost.ghostSlider(
            [stepDict["mgearRun"].components["mouthSlide_C0"].ctl,
             stepDict["mgearRun"].components["mouthCorner_L0"].ctl,
             stepDict["mgearRun"].components["mouthCorner_R0"].ctl],
            stepDict["facial_base"].surface_slider,
            self.setup_root)

        # connect scale
        pm.connectAttr(
            self.mouthSlide_ctl.scale,
            stepDict["mgearRun"].components["mouthSlide_C0"].ctl.scale)
        pm.connectAttr(
            self.cornerL_ctl.scale,
            stepDict["mgearRun"].components["mouthCorner_L0"].ctl.scale)
        pm.connectAttr(
            self.cornerR_ctl.scale,
            stepDict["mgearRun"].components["mouthCorner_R0"].ctl.scale)

        # connect pucker
        pm.connectAttr(self.mouthSlide_ctl.tz,
                       stepDict["mgearRun"].components["mouthSlide_C0"].ctl.tz)

    def connect(self, stepDict):
        # connect  to chain the deformation with another local rig.

        blendShapes.connectWithBlendshape(
            stepDict["proportions"].head_geo, self.head_geo)

First up, to share code instead of indenting everything (indenting makes “pre-formatted” instead of “code”), please use this format, and then you’ll have proper Python syntax highlighting, and people can copy paste the code into a text editor.

Surround your code with triple backticks and put the python keyword so the forum knows it is python:

```python
# your code
for eachThing in allTheThings:
    print(2 + 4.0)
    myThings = ["things", "stuff"]
```

In the workshop and in those scripts, is there a place where you are supposed to define the paths to your assets and data? Sometimes if a PATH fails, you’ll end up getting a confusing error message that seems unrelated, but it’s just because something else failed to get defined properly.

So my guess:

  1. Either something in the code has changed in the couple years since this code was written. And maybe this is a bug.
  2. Or possibly since there are a bunch of warnings around mouthSlide_C0_ctl_ghost and mouthCorner_R0_ctl_ghost, there might be something else that you need to exist in your scene.
  3. Or, you need to fix your path where self.stepDict[“paths”] would get defined. So in the workshop, it looks like it is inside build/scripts/pre/paths.py and I assume there were some instructions about how to set that up. Does that sound familiar?

In the file 01_facial_base.py there is a method, def import_surface(self, stepDict): and that is where it seems to define self.surface_slider. If this path command is maybe failing, it might explain why that definition never gets made: pm.importFile(os.path.join(self.stepDict["paths"].asset_path, "surface.ma"))

That’s all I can think of for now!

1 Like

Or, you need to fix your path where self.stepDict[“paths”] would be defined. :thinking:
This is where my mistake was. thank you very much I can move forward. :sweat_smile: :hugs:

2 Likes

When creating the objects with ghost extension this message appears, I think it is only a message and it is not an error, since the final result I can manipulate the created objects without problems, I need a confirmation that I am on the right way.

My greatest wish is that it was a warning message only, and that it does not mean that there is something wrong with the scene. I have the feeling that a lot has changed between mgear 3.6 from the videotutorial and version 4.2.2.

// Warning: mouthSlide_C0_ctl.uiHost_cnx don't have counterpart channel onmouthSlide_C0_ctl_ghost
// Warning: mouthSlide_C0_ctl.compRoot don't have contrapart channel on mouthSlide_C0_ctl_ghost
// Warning: mouthCorner_L0_ctl.uiHost_cnx has no counterpart channel in mouthCorner_L0_ctl_ghost
// Warning: mouthCorner_L0_ctl.compRoot has no counterpart channel in mouthCorner_L0_ctl_ghost
// Warning: mouthCorner_R0_ctl.uiHost_cnx has no counterpart channel in mouthCorner_R0_ctl_ghost
// Warning: mouthCorner_R0_ctl.compRoot has no counterpart channel in mouthCorner_R0_ctl_ghost

  • Warnings like mouthSlide_C0_ctl.uiHost_cnx don't have contrapart channel on mouthSlide_C0_ctl_ghost suggest that some attributes on the original controllers don’t have corresponding channels on the ghost controllers.

  • These warnings usually occur when the ghost function attempts to mirror attributes from the original controls to the ghost controls but can’t find matching attributes to link.

VideoTutorial Mouth slide custom step

Link to the folder with the scene that I am taking as a test and all its necessary elements so that the person who wants to do the same test can try it. Geometry-Scripts-etc

My Folder to Scene Test

Installing the version mGear 3.6 in Maya 2020 that is used in the Datacentric video, there are no warning messages when creating the ghost controls.
From then on the following versions I get the warning message. I just wanted to put it on record, is there anyone here who still uses the datacentric workflow to the letter and can shed light on the matter?