Posted on Leave a comment

What is interpBlendShape?

interpBlendShape is a custom Maya deformer, similar in purpose to Maya’s built-in blendShape deformer, but with surface UV interpolation, in-between support, and Bezier-style blending instead of traditional linear interpolation. It supports both meshes and curves.

The tool is designed for high-end facial rigging and special deformation cases where you want the deformation to slide across a surface while keeping the result smooth, clean, and controllable. In some cases, it can also help achieve a more graphic or 2D-style deformation look.

One of the most common challenges in facial rigging is handling large mouth shapes. Traditional linear blendShape interpolation can often produce unpleasant or unnatural in-betweens. With surface-based blending, you can focus mainly on sculpting the final target shape, while the in-between motion slides across the NURBS surface or mesh surface you provide.

In a traditional Maya setup, solving this kind of deformation can be difficult and inefficient. Workflows using UV Pin, 2D projection, or multiple built-in Maya nodes can become complicated and heavy, especially for production rigs. interpBlendShape simplifies this workflow into a single deformer, with TBB parallel processing and GPU acceleration to help keep the deformation fast and interactive.

Currently, interpBlendShape supports NURBS surface blending, where the target shape blends over the surface. You can use Cache Mode for significantly faster evaluation, or Live Mode, which allows you to drag targets and have them slide along the surface when targetOffset is set to zero.

The deformer also includes Bezier Blend as an alternative interpolation method when you do not want to use a surface. With Bezier Blend, you can create multiple in-between targets to produce a more rotational style of interpolation, which is useful for shapes like eye closing, eyebrow twisting, or other areas where you may not want to rely on many extra joints.

interpBlendShape also comes with the interpBlendShape Editor, a dedicated UI for creating, deleting, and editing deformations more easily. The editor supports real-time Maya synchronization and full undo/redo. Since the UI uses callbacks to stay synchronized with Maya, it is recommended to close the editor while playing animation, as deformation evaluation can trigger many callbacks and may slow down playback.

The editor also supports normalized weight painting, making it easier to split weights using normalize groups. In addition, mirror and flip operations for targets and weights are significantly faster than Maya’s default workflow, especially on higher-resolution meshes. During mirror and flip operations, unnecessary callbacks are suppressed to improve performance.

interpBlendShape is free for individual users. I hope this tool can be useful in your work, and feel free to contact me if you have any questions.

For more detailed technical information, including setup, attributes, and workflow examples, please refer to the interpBlendShape documentation.

You can download the sample file here:

interpBlendShape_example (558 downloads )

Thank you!

Posted on Leave a comment

only one column of a QTreeView/QTreeWidget editable只让一列可以编辑

如果你不写gui,可能不会在意maya channelBox的ui是如何实现的。最近一个工具需要用属性栏来显示和设置参数,当然思路有很多种。我使用QTreeView and QStandardItemModel 来实现的。因为我需要选择设置参数时能同时选中它的标签,但是标签那一栏需要设置为不可编辑,只做显示用。

只要override flags 方法即可

1
2
3
4
5
    def flags(self,index):
        flags = QtCore.Qt.ItemIsEnabled|QtCore.Qt.ItemIsSelectable
        if index.isValid() and index.column()==1:
            flags|= QtCore.Qt.ItemIsEditable
        return flags

如果使用的是QTreeWidget只有使用openPersistentEditor()和closePersistentEditor()来解决这一问题

1
2
3
4
5
6
7
8
9
10
11
        self._lastOpen = None
        self.itemDoubleClicked.connect(self.openEditStatus)
        self.itemSelectionChanged.connect(self.closeEditStatus)
    def closeEditStatus(self):
        if self._lastOpen:
            self.closePersistentEditor(self._lastOpen,1)
            self._lastOpen = None
    def openEditStatus(self):
        if self.currentColumn() == 1:
            self.openPersistentEditor(self.currentItem(),1)
            self._lastOpen = self.currentItem()