貝塞爾(Bezier)曲線節點

在網上看到一個bezier曲線的公式,那就用Maya的節點來實現下,看看效果,具體公式如下圖:
在這裏插入圖片描述
這個是二維的,三維的化再加個z軸向就行,


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')

核心的代碼就這一句
sum = p1 * pow(1 - t, 3) + p2 * 3 * t * pow(1 - t, 2) + p3 * 3 * pow(t, 2) * (1 - t) + p4 * pow(t, 3)
t爲小球在Bezier曲線上的位置,這裏設置爲1到0,也就是從起始位置到結束位置。

在Maya裏掛載下就可以執行我們的操作了

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)

這是最後的實際效果

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章