Bezier curve node

If you see a formula of bezier curve on the Internet, you can use Maya's nodes to realize it and see the effect. The specific formula is as follows:

This is a two-dimensional, three-dimensional transformation plus a z-axis,

import maya.OpenMayaMPx as OpenMayaMPx
import maya.OpenMaya as OpenMaya


class BezierCubic(OpenMayaMPx.MPxNode):
    kPluginNodeId = OpenMaya.MTypeId(0x00000121)

    aP1 = OpenMaya.MObject()
    aP2 = OpenMaya.MObject()
    aP3 = OpenMaya.MObject()
    aP4 = OpenMaya.MObject()

    aSum = OpenMaya.MObject()
    aBias = OpenMaya.MObject()

    def __init__(self):
        OpenMayaMPx.MPxNode.__init__(self)

    def compute(self, plug, data):

        p1 = data.inputValue(BezierCubic.aP1).asVector()
        p2 = data.inputValue(BezierCubic.aP2).asVector()
        p3 = data.inputValue(BezierCubic.aP3).asVector()
        p4 = data.inputValue(BezierCubic.aP4).asVector()
        t = data.inputValue(BezierCubic.aBias).asFloat()

        sum = p1 * pow(1 - t, 3) + p2 * 3 * t * pow(1 - t, 2) + p3 * 3 * pow(t, 2) * (1 - t) + p4 * pow(t, 3)

        outputData = data.outputValue(BezierCubic.aSum)
        outputData.set3Double(sum[0], sum[1], sum[2])

        data.setClean(plug)


def creator():
    return OpenMayaMPx.asMPxPtr(BezierCubic())


def initialize():
    nAttr = OpenMaya.MFnNumericAttribute()

    BezierCubic.aP1 = nAttr.create('Point1', 'p1', OpenMaya.MFnNumericData.k3Double)
    BezierCubic.addAttribute(BezierCubic.aP1)

    BezierCubic.aP2 = nAttr.create('Point2', 'p2', OpenMaya.MFnNumericData.k3Double)
    BezierCubic.addAttribute(BezierCubic.aP2)

    BezierCubic.aP3 = nAttr.create('Point3', 'p3', OpenMaya.MFnNumericData.k3Double)
    BezierCubic.addAttribute(BezierCubic.aP3)

    BezierCubic.aP4 = nAttr.create('Point4', 'p4', OpenMaya.MFnNumericData.k3Double)
    BezierCubic.addAttribute(BezierCubic.aP4)

    BezierCubic.aSum = nAttr.create('SumBezier', 'sum', OpenMaya.MFnNumericData.k3Double)
    nAttr.setWritable(True)
    BezierCubic.addAttribute(BezierCubic.aSum)

    BezierCubic.aBias = nAttr.create('Bias', 't', OpenMaya.MFnNumericData.kFloat, 0.0)
    nAttr.setSoftMin = 0.0
    nAttr.setSoftMax = 1.0
    nAttr.setKeyable(True)
    nAttr.setWritable(True)
    BezierCubic.addAttribute(BezierCubic.aBias)

    BezierCubic.attributeAffects(BezierCubic.aBias, BezierCubic.aSum)
    BezierCubic.attributeAffects(BezierCubic.aP1, BezierCubic.aSum)
    BezierCubic.attributeAffects(BezierCubic.aP2, BezierCubic.aSum)
    BezierCubic.attributeAffects(BezierCubic.aP3, BezierCubic.aSum)
    BezierCubic.attributeAffects(BezierCubic.aP4, BezierCubic.aSum)


def initializePlugin(obj):
    plugin = OpenMayaMPx.MFnPlugin(obj, 'Chuck', '1.0', 'Bezier')
    try:
        plugin.registerNode('BezierCubic', BezierCubic.kPluginNodeId, creator, initialize)

    except:
        raise RuntimeError('Failed to register node')


def uninitializePlugin(obj):
    plugin = OpenMayaMPx.MFnPlugin(obj)
    try:
        plugin.deregisterNode(BezierCubic.kPluginNodeId)

    except:
        raise RuntimeError('Failed to unregister node')

The core code is this sentence
sum = p1 * pow(1 - t, 3) + p2 * 3 * t * pow(1 - t, 2) + p3 * 3 * pow(t, 2) * (1 - t) + p4 * pow(t, 3)

We can mount it in Maya to perform our operation

import maya.cmds as cmds

from math import *

l1 = cmds.spaceLocator(n='loc1')
cmds.xform(l1, t=(-6, 0, -2), ws=1)

l2 = cmds.spaceLocator(n='loc2')
cmds.xform(l2, t=(-5, 0, -6), ws=1)

l3 = cmds.spaceLocator(n='loc3')
cmds.xform(l3, t=(1, 0, -6), ws=1)

l4 = cmds.spaceLocator(n='loc4')
cmds.xform(l4, t=(2, 0, -2), ws=1)

for i in range(0, 11):
    node_name = 'BezierCubic' + str(i)
    sphere_name = 'sphere' + str(i)
    sphere = cmds.sphere(n=sphere_name, r=.5)
    cmds.createNode('BezierCubic', n=node_name)
    cmds.connectAttr('loc1.translate', node_name + '.Point1')
    cmds.connectAttr('loc2.translate', node_name + '.Point2')
    cmds.connectAttr('loc3.translate', node_name + '.Point3')
    cmds.connectAttr('loc4.translate', node_name + '.Point4')
    cmds.connectAttr(node_name + '.SumBezier', sphere_name + '.translate')
    cmds.setAttr(node_name + '.Bias', i / 1.0 * 0.1)

This is the final practical effect

Published 67 original articles, won praise 22, visited 60000+
Private letter follow

Tags: P4

Posted on Sat, 14 Mar 2020 08:30:37 -0700 by moose4204l