It’s not very difficult to link a tape’s length to a text object’s text.
If you run this in an empty scene it should create a linked tape and text object.
(
theTape = tape pos:[0,0,0] target:(targetObject pos:[0,100,0])
theText = text size:10 pos:[25,0,0]
theText.text = (distance theTape theTape.target) as string
when transform theTape changes id:#tape2text handleAt:#redrawViews do
(
theText.text = (distance theTape theTape.target) as string
)
)
/*
Type this into the MAXScript listener to break the link
deleteAllChangeHandlers id:#tape2text
*/
On a slightly connected note! I wouldn’t mind a similar thing but having a text object display the rotation of a camera/object in Z, ie 275 degrees/or just the rotation value from the Z as I cant work out how to get max to display rotations in degrees.
(
theCam = VRayPhysicalCamera pos:[0,0,0] targeted:false
camr = eulerangles 90 0 0
rotate theCam camr
theText = text size:10 pos:[25,0,0]
theText.text = ((quatToEuler2 (theCam.transform.rotationPart)).z) as string
when transform theCam changes id:#cam2text handleAt:#redrawViews do
(
theText.text = ((quatToEuler2 (theCam.transform.rotationPart)).z) as string
)
)
/*
Type this into the MAXScript listener to break the link
deleteAllChangeHandlers id:#cam2text
*/
How are you using these, are you writing your own script?
Sorry Mark i haven’t got time to do this properly. I’ve modified the script so that if you run the script then click on a camera it adds a text object to that camera. You can then repeat this for any number of cameras now.
(
fn camFil cam =
(
superClassOf cam == camera
)
theCam = pickObject filter:camFil
theCamHand = GetHandleByAnim theCam
theText = text name:(theCam.name+" Angle") size:10 pos:(theCam.pos+[25,0,0])
theText.parent = theCam
theTextHand = GetHandleByAnim theText
theText.text = formattedPrint ((quatToEuler2 (theCam.transform.rotationPart)).z) format:"0.3g"
when transform (GetAnimByHandle theCamHand) changes id:#cam2text do
(
if IsValidNode (GetAnimByHandle theTextHand) then
(
(GetAnimByHandle theTextHand).text = formattedPrint ((quatToEuler2 ((GetAnimByHandle theCamHand).transform.rotationPart)).z) format:"0.3g"
rotate (GetAnimByHandle theTextHand) (inverse (GetAnimByHandle theTextHand).rotation)
)
)
)
/*
Type this into the MAXScript listener to break the link
deleteAllChangeHandlers id:#cam2text
*/
I wrote one as well that I love. It’s quick and not fancy at all, because I wrote it on set for a shoot and didn’t have much time. Just click the script, and then draw a line (just like a normal) spline. It will put the measurements in between each segment of the line. No callbacks, no frills. Redraw your line if you mess up.
Enjoy,
Colin
macroScript measureHelper category:"ColinScripts" tooltip:"Measure Helper" Icon:#("Helpers",5) (
(
global theDist, groupNode, getRotateAngles
fn setColor o = o.wirecolor = green
fn getRotateAngles = (
-- Orient the text correctly
case viewport.getType() of (
#view_bottom: (eulerAngles 180 0 0)
#view_right: (eulerAngles 90 0 90)
#view_left: (eulerAngles 90 0 -90)
#view_front: (eulerAngles 90 0 0)
#view_back: (eulerAngles 90 0 180)
default: (eulerAngles 0 0 0)
)
)
tool placeText prompt:"Select Placement for Text" numPoints:1 (
local b
on mousePoint clickno do (
if clickno == 1 then b = text pos:worldPoint text:(theDist as string) size:5 else #stop
b.wirecolor = green
-- Orient the text correctly
rotate b getRotateAngles()
attachNodesToGroup b groupNode
)
)
local measureLine = startObjectCreation line returnNewNodes:true newNodeCallback:setColor
measureLine = measureLine[1]
if measureLine != undefined and (numKnots measureLine) >= 2 then (
-- Measure the distance between knots
local pt, prevpt
groupNode = group measureLine name:(uniqueName "Measure Group")
1
for k = 1 to (numKnots measureLine) do (
pt = (getKnotPoint measureLine 1 k)
-- Create Dummies at the knots
d = dummy pos:pt name:(measureLine.name+"_knot_"+k as string) scale:[.2,.2,.2]
attachNodesToGroup d groupNode
if k > 1 then (
theDist = distance prevpt pt
local midpt = point3 ((prevpt.x + pt.x)/2) ((prevpt.y + pt.y)/2) ((prevpt.z + pt.z)/2)
local distanceText = text pos:midpt text:(theDist as string) size:5
distanceText.wirecolor = green
rotate distanceText (getRotateAngles())
attachNodesToGroup distanceText groupNode
--messageBox ("Click for Text Placement: " + (k-1) as string + " of " + (((numKnots measureLine)-1) as string))
--starttool placeText
--format "distance between % and %: %\n" prevpt pt (distance prevpt pt)
)
prevpt = pt
)
) else
messageBox "Problem with created Measuring Spline, undefined or less than 2 knots."
)
)
Hey thanks for posting this Colin! Just been trying it and works really well. I will have to make the text larger as we work in mm but I can definitely see myself using it. Surprising that there isn’t something like this in Max already really.
@m_hinks Did the last script do want you wanted it to?
Hi Colin, yes its very useful, I can see that coming in handy.
Dan, thanks again. It is perfect for the job, except for one thing which I just found out! I have made a template file with a couple of these tapes so I can merge into files where I need it. But the script seems to be getting lost when I merge to a new scene? I’m not sure if there is any way to add the script to the new scene, or whether the method of linking the text to the length can be done on the object?
No, the when construct that I used won’t survive merging into a different scene or even saving and reopening the scene.
Here’s a different way of linking the text tape which should at least survive the scene being saved and reloaded. Not tested merging though.