got the vector, how to use it?


#1

I’m attempting to build a script that builds a ribbon along a joint chain. I’ve build the curve, now I need to duplicate it on ether side in order to build a loft. But what direction is “ether side”. I want to build this making no assumptions (except the joints don’t right straight up. I’ll address this assumption later) about what directions the joints are running (relating to x or z axis), as well as how the joints have been oriented (be they oriented with X down the joint, or Z down the joint. So far, I’m able to get the vector for the joint chains general direction (vector between the start and end joints), but am uncertain how to make use of this to duplicate curves on ether side of the base curve (in other words, how do I get the vector for 2 and -2 units perpendicular, from the vector I have now?). Attached bellow is the code I have so far.

PS: if anyone can recommend good beginner-intermediate vector math tutorials, I’d appreciate the resource.

import maya.cmds as cmds
import maya.OpenMaya as om
SJNT="joint1"
EJNT="joint6"
AllKids=cmds.listRelatives(SJNT, ad=1)
iCount=1
if EJNT in AllKids:
	Chain={}
	Test=True
	JNT=EJNT
	killIt=0
	#get the position of all joints between the end of ribbon joint and the start of ribbon joint
	while Test==True:
		print "Current Joint = %s" %JNT
		if cmds.nodeType(JNT)=="joint":
			Chain["JNT_%d" %iCount]=cmds.xform(JNT, q=1, ws=1, t=1)
			if JNT==SJNT:
				test=False
			iCount=iCount+1
			killIt=0
		else:
			killIt=killIt+1
		
		if killIt==3:
			Test=False
		NewJNT=cmds.listRelatives(JNT, p=1)
		if NewJNT:
			JNT=NewJNT[0]
		else:
			Test=False
		if iCount==100:
			Test=False
else:
	cmds.warning("======== Start and end joints are not within the same joint chain ========")

CLen=len(Chain)
CrvOps=[]
CRV=cmds.curve(n="tempCrv", p=[Chain["JNT_%d" %CLen]])
for each in range(1, CLen):
	num=CLen-each
	cmds.curve(CRV, a=1, p=[Chain["JNT_%d" %num]])


EJNTVc=om.MVector(Chain["JNT_1"][0],Chain["JNT_1"][1],Chain["JNT_1"][2])
SJNTVc=om.MVector(Chain["JNT_%d" %CLen][0],Chain["JNT_%d" %CLen][1],Chain["JNT_%d" %CLen][2])

StartEnd=EJNTVc-SJNTVc


finalV=StartEnd
PVLOC=cmds.spaceLocator(n="CNT_Knee_PV_")
cmds.xform(PVLOC, ws=1, t=(finalV.x,finalV.y,finalV.z))
#get direction curve is going (on X or Z) in order to slide it side to side




#2

Well, I’ve worked out an alternative route to get what I wanted, though it is a rather inelegant, even dirty approach, creating locators and moving them about to get their worldspace translation coordinates. If someone is able to provide a better solution, I would very much appreciate it…

This test code assumes a joint chain containing 6 or more joints, with their default names


import maya.OpenMaya as om
SJNT="joint1"
EJNT="joint6"
name="Spine"
AllKids=cmds.listRelatives(SJNT, ad=1)
iCount=1
if EJNT in AllKids:
	Chain={}
	Test=True
	JNT=EJNT
	killIt=0
	while Test==True:
		print "Current Joint = %s" %JNT
		if cmds.nodeType(JNT)=="joint":
			Chain["JNT_%d" %iCount]=cmds.xform(JNT, q=1, ws=1, t=1)
			if JNT==SJNT:
				test=False
			iCount=iCount+1
			killIt=0
		else:
			killIt=killIt+1
		
		if killIt==3:
			Test=False
		NewJNT=cmds.listRelatives(JNT, p=1)
		if NewJNT:
			JNT=NewJNT[0]
		else:
			Test=False
		if iCount==100:
			Test=False
else:
	cmds.warning("======== Start and end joints are not within the same joint chain ========")

CLen=len(Chain)
CrvOps=[]
CRV=cmds.curve(n="tempCrv", p=[Chain["JNT_%d" %CLen]])
for each in range(1, CLen):
	num=CLen-each
	cmds.curve(CRV, a=1, p=[Chain["JNT_%d" %num]])


EJNTVc=om.MVector(Chain["JNT_1"][0],Chain["JNT_1"][1],Chain["JNT_1"][2])
SJNTVc=om.MVector(Chain["JNT_%d" %CLen][0],Chain["JNT_%d" %CLen][1],Chain["JNT_%d" %CLen][2])

StartEnd=EJNTVc-SJNTVc

finalV=StartEnd.normal()
PVLOC=cmds.spaceLocator(n="Ribbon_Aim_Temp")
cmds.xform(PVLOC, ws=1, t=(finalV.x,0,finalV.z))
#get direction curve is going (on X or Z) in order to slide it side to side
#find a more elegant way to do the following
PVLOC2=cmds.spaceLocator(n="Ribbon_Room_Temp")
NULL=cmds.group(n="TEMP_Ribbon_NULL", em=True)
cmds.parent(PVLOC2, NULL)
AC=cmds.aimConstraint(PVLOC, NULL) 
cmds.move(0,0,.5, PVLOC2, ls=1)
POSPOS=cmds.xform(PVLOC2, q=1, ws=1, t=1)
cmds.move(0,0,-.5, PVLOC2, ls=1)
NEGPOS=cmds.xform(PVLOC2, q=1, ws=1, t=1)
cmds.delete(AC, NULL, PVLOC)

CRV2=cmds.duplicate(CRV)
cmds.xform(CRV2, ws=1, t=POSPOS)
CRV3=cmds.duplicate(CRV)
cmds.xform(CRV3, ws=1, t=NEGPOS)

LOFT=cmds.loft(CRV2, CRV3, n=name+"_RIBBON_C")