def create_ribbon(numJoints=10, prefix='testRibbon', numSpans=5, startObj=None, endObj=None): rigGrp = pm.group(empty=True, name='%s_rig_grp' %prefix) ctrlGrp = pm.group(empty=True, name="%s_ctrl_grp" %prefix) proxyGrp = pm.group(empty=True, name="%s_proxy_grp" %prefix) ctrlGrp.overrideDisplayType.set(1) #template proxyGrp.visibility >> ctrlGrp.overrideEnabled #=========================================================================== # proxy #=========================================================================== proxy_start = pm.spaceLocator(name='%s_root_start' %prefix) pm.parent( proxy_start.add_parent_group(suffix='const'), proxyGrp) proxy_end = pm.spaceLocator(name='%s_root_end' %prefix) proxy_end.tx.set(1) pm.parent( proxy_end.add_parent_group(suffix='const'), proxyGrp) #=========================================================================== # proxy #=========================================================================== rootCtrl = pm.spaceLocator(name='%s_root_ctrl' %prefix) pm.parent(pm.parentConstraint(proxy_start, rootCtrl, mo=False), proxyGrp) pm.parent(rootCtrl, ctrlGrp) proxy_up = pm.spaceLocator(name='%s_root_up' %prefix) proxy_up.ty.set(1) pm.parent( proxy_up.add_parent_group(suffix='const'), proxyGrp) proxy_mid = pm.spaceLocator(name='%s_root_mid' %prefix) proxy_mid.tx.set(1) proxy_mid_const = proxy_mid.add_parent_group(suffix='const') pm.parent( proxy_mid_const, proxyGrp) pm.pointConstraint(proxy_start, proxy_end, proxy_mid_const, mo=False) pm.aimConstraint(proxy_end, proxy_start, aimVector=[1,0,0], upVector=[0,1,0], worldUpType='object', worldUpObject=proxy_up.name()) pm.aimConstraint(proxy_start, proxy_end, aimVector=[-1,0,0], upVector=[0,1,0], worldUpType='object', worldUpObject=proxy_up.name()) pm.parentConstraint(rootCtrl, rigGrp, mo=False) #=========================================================================== # ribbon plane #=========================================================================== ribbonGrp = pm.group(empty=True, name="%s_ribbon_grp" %prefix) pm.parent(ribbonGrp, rigGrp) follicleGrp = pm.group(empty=True, name="%s_follicle_grp" %prefix) pm.parent(follicleGrp, rigGrp) follicleGrp.inheritsTransform.set(0) follicleGrp.overrideDisplayType.set(2) #reference proxyGrp.visibility >> follicleGrp.overrideEnabled ribbonName = "%s_ribbon" %prefix ribbon = pm.nurbsPlane(ax=[0,1,0], w=1, lr=0.05, d=3, u=10, v=1, ch=0, name=ribbonName)[0] ribbon.translateX.set(0.5) ribbon.rotateX.set(90) pm.makeIdentity(ribbon, apply=True, t=1 ,r=1 ,s=1, n=0 ,pn=1) ribbon.scalePivot.set(0,0,0) ribbon.rotatePivot.set(0,0,0) pm.parent(ribbon, ribbonGrp) ribbonGrp.visibility.set(0) #proxy_start.rotateX >> ribbon.rotateX #=========================================================================== # ribbon follicles / joints #=========================================================================== joints = [] proxyCubes = [] spacing = (1.0/(numJoints-1)) for i in range(numJoints): uPos = i * spacing jointName = "%s_%d" %(prefix, i+1) fol = create_follicle(ribbon, uPos, 0.5) fol_trans = fol.getParent() pm.select(clear=True) joint = pm.joint(name=jointName) #======================================================================= cube = pm.polyCube(w=spacing, h=spacing, d=spacing, ch=False)[0] pm.parentConstraint(joint, cube) pm.parent(cube, joint) # pm.parent(cube, proxyGrp) proxyCubes.append(cube) cube.overrideEnabled.set(1) cube.overrideDisplayType.set(2) #reference #======================================================================= pm.parent(joint, fol_trans, r=True) pm.parent(fol_trans, follicleGrp) joints.append(joint) #=========================================================================== # ribbon wires #=========================================================================== wireGrp = pm.group(empty=True, name="%s_wire_grp" %prefix) pm.parent(wireGrp, rigGrp) wireCtrlGrp = pm.group(empty=True, name='%s_wire_ctrl_grp' %prefix) pm.parent(wireCtrlGrp, rootCtrl) wireCtrlGrp.inheritsTransform.set(0) wireName = '%s_wire' %prefix wireCurve = pm.curve(d=2, p=[[0,0,0],[0.5,0,0],[1,0,0]], k=[0,0,1,1], name=wireName) mel.eval("rebuildCurve -ch 0 -rpo 1 -rt 0 -end 1 -kr 0 -kcp 0 -kep 1 -kt 0 -s %d -d 2 %s" %(numSpans, wireCurve.name())) wire2, wireCurve, wireBaseCurve = wire_deformer( wireCurve, ribbon) pm.parent(wireCurve, wireBaseCurve, wireGrp) #pm.reorderDeformers(wire1, wire2, ribbon) #=========================================================================== # ribbon curve/ctrls #=========================================================================== curve = pm.curve(d=2, p=[[0,0,0],[0.5,0,0],[1,0,0]], k=[0,0,1,1], name="%s_curve"%prefix) pm.parent(curve, ribbonGrp) #wire1, curve, baseCurve = wire_deformer( curve, wireCurve) ctrls=[] for cv in curve.cv: clusterName = '%s_curve%d_cluster' %(prefix, cv.index()) ctrlName = "%s_curve%d_ctrl" %(prefix, cv.index()) cluster, clusterHandle = pm.cluster(cv, relative=True, name=clusterName) clusterHandle.visibility.set(0) ctrl = pm.spaceLocator(name=ctrlName) pm.delete(pm.pointConstraint(clusterHandle, ctrl, mo=False)) pm.parentConstraint(ctrl, clusterHandle) ctrls.append(ctrl) pm.parent(clusterHandle, ribbonGrp) startCtrl = ctrls[0] midCtrl = ctrls[1] endCtrl = ctrls[-1] startCtrlName = "%s_start_ctrl" %prefix endCtrlName = "%s_end_ctrl" %prefix startCtrl.rename("%s_start_ctrl" %prefix) startConst = startCtrl.add_parent_group(suffix='const') pm.parent(pm.parentConstraint(proxy_start, startConst, mo=False), proxyGrp) endCtrl.rename("%s_end_ctrl" %prefix) endConst = endCtrl.add_parent_group(suffix='const') pm.parent(pm.parentConstraint(proxy_end, endConst, mo=False), proxyGrp) midCtrl.rename("%s_mid_ctrl" %prefix) midConst = midCtrl.add_parent_group(suffix='const') pm.parent(pm.parentConstraint(proxy_mid, midConst, mo=False), proxyGrp) startCtrl.getShape().localPositionX.set(-1) endCtrl.getShape().localPositionX.set(1) pm.parent(startConst, endConst, midConst, rootCtrl) #=========================================================================== # ribbon wire cluster #=========================================================================== for cv in wireCurve.cv: #cluster / ctrl clusterName = '%s_wire%d_cluster' %(prefix, cv.index()) ctrlName = "%s_wire%d_ctrl" %(prefix, cv.index()) cluster, clusterHandle = pm.cluster(cv, relative=True, name=clusterName) ctrl = pm.spaceLocator(name=ctrlName) pm.delete(pm.pointConstraint(clusterHandle, ctrl, mo=False)) pm.parentConstraint(ctrl, clusterHandle) pm.scaleConstraint(ctrl, clusterHandle) #ctrl.t >> clusterHandle.t #ctrl.r >> clusterHandle.r #ctrl.s >> clusterHandle.s ctrls.append(ctrl) pm.parent(clusterHandle, wireGrp) #revit revit = pm.spaceLocator(name="%s_revit" %ctrl.name()) revit.getShape().localScale.set(0,0,0) pm.delete(pm.parentConstraint(ctrl, revit, mo=False)) pm.parent(ctrl, revit) revit_locator_to_curve(revit, curve) rootCtrl.r >> revit.r pm.parent(revit, wireCtrlGrp) wireGrp.visibility.set(0) #=========================================================================== # twist #=========================================================================== twistGrp = pm.group(empty=True, name="%s_twist_grp" %prefix) pm.parent(twistGrp, rigGrp) startTwist = pm.group(empty=True, name="%s_start_twist" %prefix) startTwistAim = startTwist.add_parent_group(suffix='aim') pm.pointConstraint(startCtrl, startTwistAim, mo=False) endTwist = pm.group(empty=True, name="%s_end_twist" %prefix) endTwistAim = endTwist.add_parent_group(suffix='aim') pm.pointConstraint(endCtrl, endTwistAim, mo=False) startTwistUp = pm.spaceLocator(name="%s_start_twistUp" %prefix) pm.delete(pm.parentConstraint(startCtrl, startTwistUp, mo=False)) startTwistUp.ty.set(1) pm.parentConstraint(startCtrl, startTwistUp, mo=True) endTwistUp = pm.spaceLocator(name="%s_end_twistUp" %prefix) pm.parentConstraint(endCtrl, endTwistUp, mo=False) endTwistUp.ty.set(1) const = pm.parentConstraint(endCtrl, endTwistUp, mo=True) pm.aimConstraint(endTwistAim, startTwistAim, aimVector=[1,0,0], upVector=[0,1,0], worldUpType='objectrotation', worldUpVector=[0,1,0], worldUpObject=startCtrl.name()) pm.aimConstraint(startTwistAim, endTwistAim, aimVector=[-1,0,0], upVector=[0,1,0], worldUpType='objectrotation', worldUpVector=[0,1,0], worldUpObject=endCtrl.name()) #pm.aimConstraint(endTwist, startTwist, aimVector=[1,0,0], upVector=[0,1,0], worldUpType='object', worldUpObject=startTwistUp.name()) #pm.aimConstraint(startTwist, endTwist, aimVector=[-1,0,0], upVector=[0,1,0], worldUpType='object', worldUpObject=endTwistUp.name()) twist, twistHdl = pm.nonLinear(ribbon , type='twist', foc=True, name='%s_twist'%prefix) twistHdl.rotateZ.set(90) startTwistAim.rx >> twist.endAngle endTwistAim.rx >> twist.startAngle #startTwist.rx >> twist.endAngle #endTwist.rx >> twist.startAngle pm.parent(startTwistUp, endTwistUp, twistHdl, startTwistAim, endTwistAim, twistGrp) twistGrp.visibility.set(0) #=========================================================================== # stretch and squash #=========================================================================== stretchGrp = pm.group(empty=True, name="%s_stretch_grp" %prefix) stretchGrp.addAttr('baseDistance', at='double') pm.parent(stretchGrp, rigGrp) stretchGrp.inheritsTransform.set(0) stretchPlane = pm.nurbsPlane(ax=[0,1,0], ch=False, w=2, lr=1, d=3, u=2, v=2, name='%s_stretch_plane'%prefix) squash, squashHdl = pm.nonLinear(stretchPlane, type='squash', foc=True, name="%s_squash"%prefix) squashHdl.rotateZ.set(90) for i in range(numJoints): spacing = i * (1.0/(numJoints-1)) pointOnSurface = pm.createNode('pointOnSurfaceInfo') stretchPlane[0].getShape().worldSpace[0] >> pointOnSurface.inputSurface pointOnSurface.parameterU.set(spacing) pointOnSurface.positionZ >> joints[i].sz pointOnSurface.positionZ >> joints[i].sy baseDistance = pm.createNode('distanceBetween', name="%s_base_distance" %prefix) proxy_start.getShape().worldPosition[0] >> baseDistance.point1 proxy_end.getShape().worldPosition[0] >> baseDistance.point2 stretchDistance = pm.createNode('distanceBetween', name="%s_stretch_distance" %prefix) stretchDistanceStart = pm.spaceLocator(name="%s_stretch_distance_start" %prefix) stretchDistanceStart.localScale.set(0,0,0) pm.parentConstraint(startCtrl, stretchDistanceStart, mo=False) stretchDistanceEnd = pm.spaceLocator(name="%s_stretch_distance_end" %prefix) stretchDistanceEnd.localScale.set(0,0,0) pm.parentConstraint(endCtrl, stretchDistanceEnd, mo=False) stretchDistanceStart.getShape().worldPosition[0] >> stretchDistance.point1 stretchDistanceEnd.getShape().worldPosition[0] >> stretchDistance.point2 strechFactor_md = pm.createNode('multiplyDivide', name='%s_stretch_distance_md' %prefix) strechFactor_md.operation.set(2) #divide baseDistance.distance >> stretchGrp.baseDistance stretchGrp.baseDistance >> strechFactor_md.input2X stretchDistance.distance >> strechFactor_md.input1X strechFactor_remap = pm.createNode('remapValue', name="%s_stretch_factor_remap" %prefix) strechFactor_md.outputX >> strechFactor_remap.inputValue strechFactor_remap.inputMin.set(0.5) strechFactor_remap.inputMax.set(1.5) strechFactor_remap.outputMin.set(-1) strechFactor_remap.outputMax.set(1) strechFactor_remap.outValue >> squash.factor pm.parent(stretchDistanceStart, stretchDistanceEnd, stretchPlane, squashHdl, stretchGrp) stretchGrp.visibility.set(0) #=========================================================================== for cube in proxyCubes: stretchGrp.baseDistance >> cube.sx stretchGrp.baseDistance >> cube.sy stretchGrp.baseDistance >> cube.sz stretchGrp.baseDistance >> ribbon.sz #=========================================================================== #=========================================================================== # Positioning #=========================================================================== if startObj and endObj: pm.delete(pm.parentConstraint(startObj, proxy_start, mo=False)) pm.delete(pm.parentConstraint(endObj, proxy_end, mo=False)) pm.delete(pm.parentConstraint(startObj, proxy_up, mo=False)) proxy_up.ty.set(proxy_up.ty.get() + 1)
def create_ribbon(numJoints=5, prefix='testRibbon', degree=None, spans=None ): rigGrp = pm.group(empty=True, name='%s_rig_grp' %prefix) root = pm.spaceLocator(name='%s_root' %prefix) #=========================================================================== # ribbon plane #=========================================================================== ribbonName = "%s_ribbon" %prefix ribbon = pm.nurbsPlane(ax=[0,1,0], w=1, lr=0.05, d=3, u=10, v=1, ch=0, name=ribbonName)[0] ribbon.translateX.set(0.5) pm.makeIdentity(ribbon, apply=True, t=1 ,r=1 ,s=1, n=0 ,pn=1) pm.parent(ribbon, rigGrp) #=========================================================================== # ribbon follicles / joints #=========================================================================== for i in range(numJoints): spacing = i * (1.0/(numJoints-1)) jointName = "%s_%d" %(prefix, i+1) fol = create_follicle(ribbon, spacing, 0.5) fol_trans = fol.getParent() pm.select(clear=True) joint = pm.joint(name=jointName) pm.parent(joint, fol_trans, r=True) pm.parent(fol, rigGrp) #=========================================================================== # ribbon wires #=========================================================================== curveName = '%s_wire' %prefix curve = pm.curve(d=2, p=[[0,0,0],[0.5,0,0],[1,0,0]], k=[0,0,1,1], name=curveName) if spans and degree: mel.eval("rebuildCurve -ch 0 -rpo 1 -rt 0 -end 1 -kr 0 -kcp 0 -kep 1 -kt 0 -s %d -d %d %s" %(spans, degree, curve.name())) wires = wire_deformer( curve.name(), ribbon.name()) pm.parent(wires, rigGrp) #=========================================================================== # ribbon wire control #=========================================================================== ctrls = [] for cv in curve.cv: clusterName = '%s_wire%d_cluster' %(prefix, cv.index()) ctrlName = "%s_wire%d_ctrl" %(prefix, cv.index()) cluster, clusterHandle = pm.cluster(cv, relative=True, name=clusterName) ctrl = pm.spaceLocator(name=ctrlName) pm.delete(pm.pointConstraint(clusterHandle, ctrl, mo=False)) pm.parentConstraint(ctrl, clusterHandle) ctrls.append(ctrl) pm.parent(clusterHandle, rigGrp) #=========================================================================== # ribbon start/end ctrls #=========================================================================== startCtrlName = "%s_start_ctrl" %prefix endCtrlName = "%s_end_ctrl" %prefix ctrls[0].rename(startCtrlName) startConst = ctrls[0].add_parentGroup(suffix='const') ctrls[-1].rename(endCtrlName) endConst = ctrls[-1].add_parentGroup(suffix='const') pm.parent(startConst, endConst, root) #=========================================================================== # mid ctrls #=========================================================================== for ctrl in ctrls[1:-1]: value = ctrl.translateX.get() ctrlConst = ctrl.add_parentGroup(suffix='const') pm.parentConstraint(ctrls[-1], ctrlConst, w=value) pm.parentConstraint(ctrls[0], ctrlConst, w=1-value) pm.parent(ctrlConst, root)