PDA

View Full Version : How to display selected object name in viewport corner


CarlCampbell
05-06-2008, 10:21 AM
Greetings!

I currently have a script that shows the current frame the timeslider is on and it would be great to have a similar function that shows me the name of the object I have selected without having to bring up the Command Panel constantly (I have it hidden by default).

This would prove especially useful when selecting objects that are out of sight. I'd play around with the frame display script by Mark Tsang that I have but I just wouldn't know when to start...

So basically I'm looking for a script that would display the name of the selected object in a corner of the viewport. I know that changing the text colour is simple so if on top of that I could change the position of the text relative to the viewport too, that would be awesome!

Many thanks in advance!

Cheers

ZeBoxx2
05-06-2008, 12:57 PM
split things up into bits...

- a function to draw the text (in any corner/edge/center)
- a function that determines the text to draw
- a callback that calls that whenever the viewport redraws


global drawSelName_s
global drawSelName

struct drawSelName_s (
strRect = (Box2 0 0 0 0),

fn drawText str pos:#(#top,#right) col:(color 0 0 0) = (
-- remove old text
gw.clearScreen drawSelName.strRect useBkg:false
gw.enlargeUpdateRect drawSelName.strRect
gw.updateScreen()

-- get the size of the text
strExtent = gw.getTextExtent str

-- get the size of the viewport
vpWidth = gw.getWinSizeX()
vpHeight = gw.getWinSizeY()

-- determine the positioning of the text
yPos = case pos[1] of (
#top: strExtent.y
#center: (vpHeight / 2.0) - (strExtent.y / 2.0)
#bottom: (vpHeight - 1)
)
xPos = case pos[2] of (
#left: 0
#center: (vpWidth / 2.0) - (strExtent.x / 2.0)
#right: vpWidth - strExtent.x - 1
)

-- draw the text
gw.setTransform (Matrix3 1)
gw.wText [xPos,yPos,0] str color:col
drawSelName.strRect = (Box2 (xPos + 1) (yPos - strExtent.y) strExtent.x (strExtent.y + 2))
gw.enlargeUpdateRect drawSelName.strRect
gw.updateScreen()
),

fn drawSelectionName = (
local sel = getCurrentSelection()
local selCount = sel.count
local selName = case of (
(selCount == 0): ""
(selCount == 1): sel[1].name
(selCount > 1): (sel.count as string + " selected")
)
drawSelName.drawText selName pos:#(#top,#right) col:(color 255 255 0)
)
)
if (drawSelName != undefined) then ( unRegisterRedrawViewsCallback drawSelName.drawSelectionName )
drawSelName = drawSelName_s()
registerRedrawViewsCallback drawSelName.drawSelectionName


Should be fairly self-explanatory - there's a single line in there that calls the text drawing function with the text to draw, the position and the color to play with.

Unfortunately I can't seem to keep the text transparent when it's over objects without running into overlap issues when it's not over objects.. must be missing something :)

davestewart
05-06-2008, 01:52 PM
Nice, Richard!

Any reason you a) kept the initialization code out of the struct and b) instantiated an instance?

This worked just great...


struct drawSelName (

fn drawText str pos:#(#top,#right) col:(color 0 0 0) = (

-- locals
local strRect = (Box2 0 0 0 0)

-- remove old text
gw.clearScreen strRect useBkg:false
gw.enlargeUpdateRect strRect
gw.updateScreen()

-- get the size of the text
strExtent = gw.getTextExtent str

-- get the size of the viewport
vpWidth = gw.getWinSizeX()
vpHeight = gw.getWinSizeY()

-- determine the positioning of the text
yPos = case pos[1] of (
#top: strExtent.y
#center: (vpHeight / 2.0) - (strExtent.y / 2.0)
#bottom: (vpHeight - 1)
)
xPos = case pos[2] of (
#left: 0
#center: (vpWidth / 2.0) - (strExtent.x / 2.0)
#right: vpWidth - strExtent.x - 1
)

-- draw the text
gw.setTransform (Matrix3 1)
gw.wText [xPos,yPos,0] str color:col
strRect = (Box2 (xPos + 1) (yPos - strExtent.y) strExtent.x (strExtent.y + 2))
gw.enlargeUpdateRect strRect
gw.updateScreen()
),

fn drawSelectionName = (
local sel = getCurrentSelection()
local selCount = sel.count
local selName = case of (
(selCount == 0): ""
(selCount == 1): sel[1].name
(selCount > 1): (sel.count as string + " selected")
)
drawSelName.drawText selName pos:#(#top,#right) col:(color 255 255 0)
),

fn start =
(
registerRedrawViewsCallback drawSelName.drawSelectionName
),

fn stop =
(
unRegisterRedrawViewsCallback drawSelName.drawSelectionName
redrawviews()
)
)

drawSelName.start()

ZeBoxx2
05-06-2008, 02:41 PM
force of habit :) usually my structs have internal variables as well, so need an instance. The initialization (viewport callbacks) stuff is outside because the struct was just for drawing selected object names' into the viewport. -When- that happens is no concern of the struct. Essentially, with the callbacks in there, the struct becomes "drawSelNameOnRedraw" :)

CarlCampbell
05-06-2008, 03:41 PM
Thank-you both! Now for some nitpicking.... Here's Mark's frame number display script, it appears that it doesn't draw the grey rectangle around the numbers like your one, can this be avoided?

Also, how can I add a margin from the viewport corner to the text? I don't even know where to enter it into the code without ruining it! :(

When multiple objects are selected, it displays 'n selected' like in the Command Panel, would it be at all possible to create a string that lists all the objects in the selection? Maybe even have it limited to 10 objects and then add a '[...]' if more than 10 are selected.

Lastly, I sort of get what Mark's written at the end of his script to make it toggleable if one were to press the button/keyboard shortcut a second time, but how would it be implemented into this one?

Cheers!

macroScript Frame_Num_Display
--enabledIn:#("max")
category:"Mark Tsang"
internalcategory:"Mark Tsang"
buttontext:"Frame Numbers"
toolTip:"Frame Numbers Display"
(
global frame_num_on = false, fn_frame_display
local currentframe, lastframe, currentframecount, lastcurrentframecount
local lastViewport
local textPos
local updateRect
local viewportsize, lastviewportsize

fn fn_cleartext =
(
local rect = gw.getTextExtent lastframe
updateRect.w = rect.x+1
updateRect.h = rect.y+1
print updaterect
gw.clearscreen updateRect useBkg:true
gw.enlargeUpdateRect updateRect
gw.updateScreen()
gw.resetUpdateRect()
)

fn fn_callback =
(
registerRedrawViewsCallback fn_frame_display
local viewsize = getViewSize()

currentframe = ""
roundcurrenttime = currenttime as integer /ticksperframe
currentframe = (roundcurrenttime as string)

textPos = [(((viewsize[1] as integer) - (6 * currentframe.count))-10),20,0]
updateRect = box2 (textPos.x) (textPos.y-(gw.getTextExtent "X").y) 0 0
lastframe = ""

)

fn fn_frame_display =
(
try
(
currentframe = ""
roundcurrenttime = currenttime as integer /ticksperframe
currentframe = (roundcurrenttime as string)
viewportsize = getViewSize()
currentframecount = currentframe.count

local needUpdate = currentframe != lastframe

local movenum = (currentframecount!=lastcurrentframecount) or (viewportsize != lastviewportsize)

if movenum do
(
fn_cleartext()

unregisterRedrawViewsCallback fn_frame_display

fn_callback()

fn_cleartext()
)

if viewport.activeViewport != lastViewport then
(
completeredraw()
lastViewport = viewport.activeViewport
)

else if needUpdate do
(
fn_cleartext()
)

if (currentframe != "") do
(
gw.wtext textPos currentframe color:(color 29 198 164)
rect = gw.getTextExtent currentframe

updateRect.w = rect.x+1
updateRect.h = rect.y+1
gw.enlargeUpdateRect updateRect
gw.updateScreen()
)
lastframe = currentframe
lastviewportsize = viewportsize
lastcurrentframecount = currentframecount
)
catch ()
)
on ischecked return frame_num_on

On execute do
(
if frame_num_on then
unregisterRedrawViewsCallback fn_frame_display
else
(
fn_callback()
)

frame_num_on = not frame_num_on
completeredraw()
updateToolbarButtons()
)

)

ZeBoxx2
05-06-2008, 05:17 PM
something like this?


global drawSelName_s
global drawSelName

struct drawSelName_s (
-- text position/style, feel free to modify
verticalPos = #top, -- #top | #center | #bottom
horizontalPos = #right, -- #left | #center | #right
textMargin = 8, -- margin around the text in pixels, 0 <= N
textColor = (color 255 255 0), -- any valid color value

-- from here on down is internal code bits
drawing = false,

strRect = (Box2 0 0 0 0),

fn drawText str pos:#(#top,#right) col:(color 0 0 0) margin:4 = (
completeRedraw()

-- get the size of the text
strExtent = gw.getTextExtent str

-- get the size of the viewport
vpWidth = gw.getWinSizeX()
vpHeight = gw.getWinSizeY()

-- determine the positioning of the text
yPos = case pos[1] of (
#top: strExtent.y + margin
#center: (vpHeight / 2.0) - (strExtent.y / 2.0)
#bottom: (vpHeight - 1) - margin
)
xPos = case pos[2] of (
#left: 0 + margin
#center: (vpWidth / 2.0) - (strExtent.x / 2.0)
#right: vpWidth - strExtent.x - 1 - margin
)

-- draw the text
gw.setTransform (Matrix3 1)
gw.wText [xPos,yPos,0] str color:col
strRect = (Box2 (xPos + 1) (yPos - strExtent.y) strExtent.x (strExtent.y + 2))
gw.enlargeUpdateRect strRect
gw.updateScreen()
),

fn drawSelectionName = (
local sel = getCurrentSelection()
local selCount = sel.count
local selName
if (selCount == 0) then ( selName = "no objects selected" )
else if (selCount == 1) then ( selName = sel[1].name )
else (
selName = ""
for i = 1 to (amin sel.count 10) do (
selName += sel[i].name + " "
)
)
drawSelName.drawText selName pos:#(verticalPos,horizontalPos) col:textColor margin:textMargin
),

fn start = (
unregisterRedrawViewsCallback drawSelectionName
registerRedrawViewsCallback drawSelectionName
redrawViews()
drawing = true
updateToolbarButtons()
),

fn stop = (
unRegisterRedrawViewsCallback drawSelectionName
redrawViews()
drawing = false
updateToolbarButtons()
)
)
drawSelName = drawSelName_s()

macroScript drawSelNames category:"Views" buttontext:"drawSelnames" toolTip:"Draw names of selected objects in viewport" (
on ischecked do ( drawSelName.drawing )
on execute do (
unregisterRedrawViewsCallback drawSelName.drawSelectionName
if (drawSelName.drawing) then ( drawSelName.stop() )
else ( drawSelName.start() )
)
)


That whole grey bar thing I still don't quite 'get'. As far as I can tell, when I clear the rect and tell it to use the background, it should just 'undraw' my text as it were, but it happily tosses in that background color instead. Anyway, this should work.

Margin parameter has been added, as you can see, and multiple objects names is hardcoded - I'm sure you can tinker with it to change it to a different maximum number of object names / different presentation, etc.

abyjoe
05-06-2008, 06:13 PM
this is good... is there a way to edit the name there too... because i my scenes the naming conventions make the names really long and I would like to have the name box a bit longer... if we can edit the name on the viewport it will be great.

ZeBoxx2
05-06-2008, 07:10 PM
the length depends on the names of the objects selected - of course it will eventually run outside the viewport, which probably isn't much good ;)

CarlCampbell
05-07-2008, 08:39 AM
Wow! Thanks so much ZeBoxx, you've become my scripting hero! I'd really love to learn how to do all this stuff because I get ideas for little tools like this all the time.

Just a question, everything seems to work great now but is there a way to make the multiple objects selected string run vertically instead of horizontally like it is now? Also, is there absolutely NO way to change the size of the gw.text?

Cheers!

CarlCampbell
05-07-2008, 10:32 AM
I bound the script to a keyboard shortcut and also added the button to the toolbar. Now when I launch MAX the .mcr opens up and displays the following error message:

--Unknown property: "drawSelectionName" is undefined

What's up with that?

JHN
05-07-2008, 10:53 AM
try this


try( unregisterRedrawViewsCallback drawSelName.drawSelectionName )catch()


I think because of a fresh max session the callback is not made.. and it tries to destroy an undefined callback, resulting in an error message.. with a try catch it will not put out a error message and continues to run the script.

-Johan

ZeBoxx2
05-07-2008, 11:18 AM
JHN: correct


New version, with added settings and such...


global drawSelectionName
unregisterRedrawViewsCallback drawSelectionName
macroScript drawSelNames category:"Views" buttontext:"drawSelnames" toolTip:"Draw names of selected objects in viewport" (
-- USER SETTINGS - modify freely
-- text position settings
verticalPos = #bottom -- vertical alignment in viewport: <enum:#top | #center | #bottom>
horizontalPos = #right -- horizontal alignment in viewport: <enum:#left | #center | #right>
margin = 8 -- margin all around the text in pixels: <int>|<array:#(<int>Top,<int>Right,<int>Bottom,<int>Left)>
lineSpacing = 0 -- amount of space between lines (if any). <int>.

-- color of the text
textColor = (color 255 255 0) -- text color: <color>

-- text settings
noSelText = "no objects selected" -- text to draw when no objects are selected: <string>
multSelStyle = #list -- display type when multiple objects are selected: <enum:#list | #text> . #list lists the objects' names, #text uses multSelText
multSelText = " selected" -- text to draw when multiple objects are selected and multSelStyle is #text: <string>
multSelListMax = 10 -- maximum number of objects' names to list. <+int>
multSelListStyle = #vertical -- <enum:#vertical | #horizontal>
multSelListSort = true -- sort object names: <bool>


-- PROGRAM SETTINGS
drawing = false

strRect = (Box2 0 0 0 0)

fn drawText str pos:#(#top,#right) col:(color 0 0 0) margin:4 lineSpacing:-4 = (
if (classof margin == integer) then ( margin = #(margin,margin,margin,margin) )

-- split up into individual lines
local lines = filterString str "\n"
local lineHeight = (gw.getTextExtent "Wj").y
local textBoxHeight = ((lines.count * lineHeight) + ((lines.count - 1) * lineSpacing ))

-- keep track of an offset
verticalOffset = case pos[1] of (
#top: 0
#center: -(textBoxHeight / 2.0) + lineHeight
#bottom: -textBoxHeight + lineHeight
)

for str in lines do (
-- get the size of the text
strExtent = gw.getTextExtent str

-- get the size of the viewport
vpWidth = gw.getWinSizeX()
vpHeight = gw.getWinSizeY()

-- determine the positioning of the text
yPos = case pos[1] of (
#top: verticalOffset + lineHeight + margin[1]
#center: verticalOffset + (vpHeight / 2.0) - (lineHeight / 2.0)
#bottom: verticalOffset + (vpHeight - 1) - margin[3]
)
xPos = case pos[2] of (
#left: 0 + margin[4]
#center: (vpWidth / 2.0) - (strExtent.x / 2.0)
#right: vpWidth - strExtent.x - 1 - margin[2]
)

-- draw the text
gw.setTransform (Matrix3 1)
gw.wText [xPos,yPos,0] str color:col
strRect = (Box2 (xPos + 1) (yPos - lineHeight) strExtent.x (lineHeight + 2))
gw.enlargeUpdateRect strRect
gw.updateScreen()

-- increment the offset
verticalOffset += lineHeight + lineSpacing
)
)

drawSelectionName = fn drawSelectionName = (
local sel = getCurrentSelection()
local selCount = sel.count
local selName
if (selCount == 0) then ( selName = noSelText )
else if (selCount == 1) then ( selName = sel[1].name )
else (
selName = ""
if (multSelStyle == #text) then ( selName = sel.count as string + multSelText )
else (
local selNames = for o in sel collect ( o.name )
if (multSelListSort) then ( sort selNames )
for i = 1 to (amin selNames.count multSelListMax) do (
selName += selNames[i] + ( if (multSelListStyle == #horizontal) then " " else "\n" )
)
)
)
drawText selName \
pos:#(verticalPos,horizontalPos) \
col:textColor \
lineSpacing:lineSpacing \
margin:margin
)

fn start = (
unregisterRedrawViewsCallback drawSelectionName
registerRedrawViewsCallback drawSelectionName
redrawViews()
drawing = true
updateToolbarButtons()
)

fn stop = (
unRegisterRedrawViewsCallback drawSelectionName
redrawViews()
drawing = false
updateToolbarButtons()
)

on ischecked do ( drawing )
on execute do (
if (drawing) then ( stop() )
else ( start() )
)
)



Settings are all explained at the top.

And no - the size of the text in the viewport can't be changed, I'm afraid.

Edit: whoops. multi-line doesn't work so well when verticalPos is #center or #bottom. Will fix -_-

Edit2: Fixed.
Edit3: *ahem* let's try that again. Fixed.
Edit4: Playback fixed (though I'm sure I had that completeRedraw() in there for a reason... )

CarlCampbell
05-07-2008, 01:08 PM
This is really taking some shape! Without having to go out of your way, how would I go about making the script colour certain objects in a different colour? Say I want it to colour all cameras/geometry/shapes in one specific colour or all objects that begin with a certain prefix. How would I do that?

Cheers!

EDIT: Whoa, I've just realised something very strange... For some reason as long as the script is active you can't play the trackbar at all! Why would that be happening?

ZeBoxx2
05-07-2008, 01:40 PM
For some reason as long as the script is active you can't play the trackbar at all! Why would that be happening?
Because of the completeRedraw() call that was in there (now removed). I'm guessing I had that in there for a reason, but I can't recall why.. removing that fixes trackbar playback and doesn't seem to have any adverse effect...yet.

Without having to go out of your way, how would I go about making the script colour certain objects in a different colour? Say I want it to colour all cameras/geometry/shapes in one specific colour or all objects that begin with a certain prefix. How would I do that?
The color is pretty much determined in the call to the text drawing function.

Right now a multiple objects list is created simply by feeding the text drawing function a single string with newline characters ( \n ) in there. The script would have to be adjusted so that each object name is its own string and then has an associated color.

There's two ways to change the script to do this..
A (hacky): feed the existing text drawing function an array of the names and an array of the colors, and have it loop over those
B (clean): separate the positioning (top-left/etc.) to a new function so that the text drawing command gets absolute coordinates. Then in the selection (list) drawing function, generate the appropriate position for each object name with the new position function and feed that to the text drawing command.

Coloring by * is pretty easily done with maxscript's basic functions. I.e. if you want all cameras blue and lights yellow, and the rest green, you'd have something like:

col = case of (
isKindOf o camera: blue
isKindOf o light: yellow
default: green
)

CarlCampbell
05-07-2008, 01:53 PM
Heh, well... I DID say I was completely MAXscript illiterate :p

Thanks for fixing the playback issue!

ZeBoxx2
05-07-2008, 05:15 PM
okay, I'm gonna guess I might have broken something somewhere, but here you go...

The important changes are related to being able to color per item (which meant re-doing the positioning, as I explained earlier).

There's 4 main color bits...
- defaultColor -- yep
- wireColor -- do you want objects' name to appear as their wire color?
- classColors -- specific colors for specific classes
- nameColors -- specific colors for object names that match a given simple expression


So, for example, with the default below, if you have any lights selected those will be bright yellow, cameras will appear cameracolor-y, and any objects with the word "red" in them in one way or another will have their name listed in bright red.

Note that this is in the order of appearance in the above list; if you have a light, it will appear bright yellow regardless of its wire color. If you have a light named "Red Light", it will appear in bright red, regardless of the fact that it is a light and regardless of its wire color.

The only other new setting is
- word spacing -- (space between items when using a horizontal layout)


global drawSelectionName
unregisterRedrawViewsCallback drawSelectionName
macroScript drawSelNames category:"Views" buttontext:"drawSelnames" toolTip:"Draw names of selected objects in viewport" (
-- USER SETTINGS - modify freely
-- text position settings
verticalPos = #top -- vertical alignment in viewport: <enum:#top | #center | #bottom>
horizontalPos = #right -- horizontal alignment in viewport: <enum:#left | #center | #right>
margin = 8 -- margin all around the text in pixels: <int>|<array:#(<int>Top,<int>Right,<int>Bottom,<int>Left)>
lineSpacing = 0 -- amount of space between lines (if any). <int>
wordSpacing = 4 -- amount of space between 'words' (objects) if any, <int>

-- color of the text
defaultColor = (color 192 192 0) -- default text color: <color>
useWireColor = true -- use wirecolor of object: <bool>
classColors = #( -- colors for specific classes: <array:#(<class>,<color>)>
#(camera,(color 96 192 255)),
#(light,(color 255 255 0))
)
nameColors = #( -- colors for specific strings found in object names: <array:#(<string>,<color>)>
#("*red*",(color 255 0 0))
)

-- text settings
noSelText = "no objects selected" -- text to draw when no objects are selected: <string>
multSelStyle = #list -- display type when multiple objects are selected: <enum:#list | #text> . #list lists the objects' names, #text uses multSelText
multSelText = " selected" -- text to draw when multiple objects are selected and multSelStyle is #text: <string>
multSelListMax = 10 -- maximum number of objects' names to list. <+int>
multSelListStyle = #vertical -- <enum:#vertical | #horizontal>
multSelListSort = true -- sort object names: <bool>


-- PROGRAM SETTINGS
drawing = false

strRect = (Box2 0 0 0 0)

fn textExtent str lineSpacing:0 = (
local lines = filterString str "\n"
local lineHeight = (gw.getTextExtent "`j").y
local extent = [0,0]
for l in lines do (
strExtent = gw.getTextExtent l
extent.x = amax extent.x strExtent.x
)
extent.y = (lines.count * lineHeight) + ((lines.count - 1) * lineSpacing)
extent
)

fn textPos str pos:#(#top,#right) offset:[0,0] = (
local lineHeight = (gw.getTextExtent "`j").y

-- get the size of the text
strExtent = gw.getTextExtent str

-- get the size of the viewport
vpWidth = gw.getWinSizeX()
vpHeight = gw.getWinSizeY()

-- determine the positioning of the text
yPos = case pos[1] of (
#top: lineHeight
#center: (vpHeight / 2.0) - (lineHeight / 2.0)
#bottom: (vpHeight - 1)
)

xPos = case pos[2] of (
#left: 0
#center: (vpWidth / 2.0) - (strExtent.x / 2.0)
#right: (vpWidth - 1) - strExtent.x
)

[xPos,yPos] + offset
)

fn drawText str pos:[16,16] col:(color 0 0 0) lineSpacing:-4 = (
-- split up into individual lines
local lines = filterString str "\n"
local lineHeight = (gw.getTextExtent "`j").y
local strExtent = gw.getTextExtent str

local verticalOffset = 0

for str in lines do (
-- draw the text
gw.setTransform (Matrix3 1)
gw.wText [pos.x,pos.y + verticalOffset,0] str color:col
strRect = (Box2 (pos.x + 1) (pos.y - lineHeight) strExtent.x (lineHeight + 2))
gw.enlargeUpdateRect strRect
gw.updateScreen()

-- increment the offset
verticalOffset += lineHeight + lineSpacing
)
)

fn getColor o = (
local col = defaultColor
if (useWireColor) then ( col = o.wirecolor )
for cc in classColors do (
if (isKindOf o cc[1]) then ( col = cc[2] )
)
for nc in nameColors do (
if (matchPattern o.name pattern:nc[1]) then ( col = nc[2] )
)
col
)

fn objSort a b = (
case of (
(a.name < b.name): -1
(a.name > b.name): 1
default:0
)
)
drawSelectionName = fn drawSelectionName = (
local sel = getCurrentSelection()

if (multSelListSort) then (
qsort sel objSort
)

local selCount = sel.count
local selName

local texts = #()
if (selCount == 0) then ( append texts #(noSelText,defaultColor) )
else (
if ((multSelStyle == #text) AND (selCount > 1)) then ( append texts #(sel.count as string + multSelText,defaultColor) )
else (
for o in sel do ( append texts #(o.name,getColor o) )
)
)

local offset = [0,0]

if (multSelListStyle == #horizontal) then (
local totalWidth = 0
for t in texts do ( totalWidth += (textExtent t[1]).x )
totalWidth += (texts.count - 1) * wordSpacing

offset.x = case horizontalPos of (
#left: 0
#center: -(totalWidth/2.0)
#right: -totalWidth
)
)


if (multSelListStyle == #vertical) then (
local totalHeight = (texts.count * (textExtent texts[1][1]).y) + ((texts.count - 1) * lineSpacing)
offset.y = case verticalPos of (
#top: 0
#center: -(totalHeight/2.0)
#bottom: -totalheight
)
)

if (classof margin == integer) then ( margin = #(margin,margin,margin,margin) )
case horizontalPos of (
#left: offset.x += margin[4]
#right: offset.x -= margin[2]
)
case verticalPos of (
#top: offset.y += margin[1]
#bottom: offset.y -= margin[3]
)


for i = 1 to texts.count do (
t = texts[i]

local pos
if (multSelListStyle == #horizontal) then (
pos = case horizontalPos of (
#left: textPos t[1] pos:#(verticalPos,horizontalPos) lineSpacing:lineSpacing offset:offset
#center: textPos t[1] pos:#(verticalPos,horizontalPos) lineSpacing:lineSpacing offset:(offset + [(textExtent t[1]).x / 2.0,0])
#right: textPos t[1] pos:#(verticalPos,horizontalPos) lineSpacing:lineSpacing offset:(offset + [(textExtent t[1]).x,0])
)
)
if (multSelListStyle == #vertical) then (
pos = case verticalPos of (
#top: textPos t[1] pos:#(verticalPos,horizontalPos) lineSpacing:lineSpacing offset:offset
#center: textPos t[1] pos:#(verticalPos,horizontalPos) lineSpacing:lineSpacing offset:(offset + [0,(textExtent t[1]).y / 2.0])
#bottom: textPos t[1] pos:#(verticalPos,horizontalPos) lineSpacing:lineSpacing offset:(offset + [0,(textExtent t[1]).y])
)
)

drawText t[1] \
pos:pos \
col:t[2] \
lineSpacing:lineSpacing \
margin:margin

if (multSelListStyle == #vertical) then ( offset.y += (textExtent t[1]).y + lineSpacing )
else ( offset.x += (textExtent t[1]).x + wordSpacing )
)
)

fn start = (
unregisterRedrawViewsCallback drawSelectionName
registerRedrawViewsCallback drawSelectionName
redrawViews()
drawing = true
updateToolbarButtons()
)


fn stop = (
unRegisterRedrawViewsCallback drawSelectionName
redrawViews()
drawing = false
updateToolbarButtons()
)

on ischecked do ( drawing )
on execute do (
if (drawing) then ( stop() )
else ( start() )
)
)

CarlCampbell
05-09-2008, 01:34 PM
That's awesome, ZeBoxx. Thanks a lot! The script's looking really great now and running smoothly. Definitely gonna be keeping this one handy :)

Is there somewhere I could find a list of the available class tags available in 3dsmax? I can't seem to find them listed in the MAXscript help files.

Cheers!

ZeBoxx2
05-09-2008, 01:51 PM
Help Topic: MAXScript Class Hierarchy

to get the class of a single selected object:
classOf $

to get the superclass of that class:

myClass = classOf $
mySuperClass = classOf myClass


Script to get the hierarchy for selected objects and print those to the Listener:

fn classHierarchyOf o = (
local theClass
local classHierarchy = #(classOf o)
while ((theClass = classOf classHierarchy[1]) != classHierarchy[1]) do (
insertItem theClass classHierarchy 1
)
classHierarchy
)
for o in (getCurrentSelection()) do (
format "% : %\n" o.name (hierarchyOf o)
)


e.g.


Omni01 : #(Value, MAXWrapper, node, light, Omnilight)
GeoSphere01 : #(Value, MAXWrapper, node, GeometryClass, GeoSphere)


You'll likely want to ignore everything from 'Value' through 'MAXWrapper' to 'node' as -all- objects in the scene are members of those classes

CGTalk Moderation
05-09-2008, 01:51 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.