Hello guys. I tried to modified Mesh Info by Roger Hyde to looks the way I like, which is mimicking how modo looks like, here is the code so far:
---------------------------------------------------------------------
-- Based on Mesh Info by; Roger Hyde
-- http://www.scriptspot.com/3ds-max/scripts/meshinfo
---------------------------------------------------------------------
(
function none =
(
if (selection.count == 1) then st = $.name
else if (selection.count >= 2) then st = "Multiple Selected"
else st = "None Selected"
ss = stringstream ""
format "%" st to:ss
return ss as string
)
function getSceneFacesAsString =
(
tf = 0
sf = 0
for o in $geometry do
(
tf += o.mesh.numFaces
if o.isSelected do sf += o.mesh.numFaces
)
tf = (dotNetClass "System.String").Format "{0:n0}" tf
sf = (dotNetClass "System.String").Format "{0:n0}" sf
ss = stringstream ""
format "GL: % (%)" tf sf to:ss
return ss as string
)
function getNumVertsAsString obj =
(
try(
tv = (dotNetClass "System.String").Format "{0:n0}" (obj.baseobject.mesh.numVerts)
sv = (dotNetClass "System.String").Format "{0:n0}" (obj.baseobject.mesh.selectedverts.count)
ss = stringstream ""
format "Verts: % (%)" sv tv to:ss
return ss as string
)catch()
)
function getNumEdgesAsString obj =
(
try(
te = (dotNetClass "System.String").Format "{0:n0}" (obj.baseobject.mesh.edges.count)
se = (dotNetClass "System.String").Format "{0:n0}" (obj.baseobject.mesh.selectededges.count)
ss = stringstream ""
format "Edges: % (%)" se te to:ss
return ss as string
)catch()
)
function getNumFacesAsString obj =
(
try(
tf = (dotNetClass "System.String").Format "{0:n0}" (obj.baseobject.mesh.numFaces)
sf = (dotNetClass "System.String").Format "{0:n0}" (obj.baseobject.mesh.selectedFaces.count)
ss = stringstream ""
format "Tris: % (%)" sf tf to:ss
return ss as string
)catch()
)
-- function getNumPolysAsString obj =
-- (
-- try(
-- tp = (dotNetClass "System.String").Format "{0:n0}" (obj.baseobject.mesh.numFaces)
-- sp = (dotNetClass "System.String").Format "{0:n0}" (obj.baseobject.mesh.selectedfaces.count)
-- ss = stringstream ""
-- format "Polys: % (%)" sp tp to:ss
-- return ss as string
-- )catch()
-- )
function isValidObject obj =
(
validclasses = #(Editable_Mesh, Editable_Poly)
for o in validclasses do
(
if classOf obj == o do return true
)
return false
)
function isMesh obj =
(
meshclasses = #(Editable_Mesh)
for o in meshclasses do
(
if classOf obj == o do return true
)
return false
)
function gridSize =
(
try(
if (activeGrid == undefined) then gs = gridPrefs.spacing
else gs = activeGrid.grid
case (units.SystemType) of
(
#Inches: (un = "in"; gs = 0.393701*gs)
#Feet: (un = "ft"; gs = 0.0328084*gs)
#Miles: (un = "mi"; gs = 6.21371e-006*gs)
#Millimeters: (un = "mm"; gs = 10*gs)
#Centimeters: (un = "cm"; gs = 1*gs)
#Meters: (un = "m"; gs = 0.01*gs)
#Kilometers: (un = "km"; gs = 1e-005*gs)
)
ss = stringstream ""
format "Grid: % %" gs un to:ss
return ss as string
)catch()
)
function drawInfo =
(
noneString = none() as string
globalString = getSceneFacesAsString() as string
vertsString = (getNumVertsAsString $) as string
edgesString = (getNumEdgesAsString $) as string
trisString = (getNumFacesAsString $) as string
-- polysString = (getNumPolysAsString $) as string
gridString = gridSize() as string
noneExtent = gw.getTextExtent noneString
globalExtent = gw.getTextExtent globalString
vertsExtent = gw.getTextExtent vertsString
edgesExtent = gw.getTextExtent edgesString
trisExtent = gw.getTextExtent trisString
-- polysExtent = gw.getTextExtent polysString
gridExtent = gw.getTextExtent gridString
nonePosX = (gw.getWinSizeX() - noneExtent.x - 10)
nonePosY = (gw.getWinSizeY() - noneExtent.y - 40)
globalPosX = (gw.getWinSizeX() - globalExtent.x - 10)
globalPosY = (gw.getWinSizeY() - globalExtent.y - 40)
vertsPosX = (gw.getWinSizeX() - vertsExtent.x - 10)
vertsPosY = (gw.getWinSizeY() - vertsExtent.y - 40)
edgesPosX = (gw.getWinSizeX() - edgesExtent.x - 10)
edgesPosY = (gw.getWinSizeY() - edgesExtent.y - 40)
trisPosX = (gw.getWinSizeX() - trisExtent.x - 10)
trisPosY = (gw.getWinSizeY() - trisExtent.y - 40)
-- polysPosX = (gw.getWinSizeX() - polysExtent.x - 10)
-- polysPosY = (gw.getWinSizeY() - polysExtent.y - 40)
gridPosX = (gw.getWinSizeX() - gridExtent.x - 10)
gridPosY = (gw.getWinSizeY() - gridExtent.y - 40)
none_line_pos = [nonePosX,nonePosY,0]
global_line_pos = [globalPosX,globalPosY,0]
verts_line_pos = [vertsPosX,vertsPosY,0]
edges_line_pos = [edgesPosX,edgesPosY,0]
tris_line_pos = [trisPosX,trisPosY,0]
-- polys_line_pos = [polysPosX,polysPosY,0]
grid_line_pos = [gridPosX,gridPosY,0]
line_height = [0, 15, 0]
if subobjectLevel != undefined then
(
if (subObjectLevel > 0) and (isValidObject (modPanel.getCurrentObject())) then
(
case subobjectlevel of
(
1:
(
gw.wText verts_line_pos (getNumVertsAsString $) color:[255,199,71]
global_line_pos += line_height
gw.wText global_line_pos (getSceneFacesAsString()) color:[165,165,165]
grid_line_pos += (line_height)*3
gw.wText grid_line_pos (gridSize()) color:[165,165,165]
)
2:
(
gw.wText edges_line_pos (getNumEdgesAsString $) color:[255,199,71]
global_line_pos += line_height
gw.wText global_line_pos (getSceneFacesAsString()) color:[165,165,165]
grid_line_pos += (line_height)*3
gw.wText grid_line_pos (gridSize()) color:[165,165,165]
)
3:
(
if isMesh (modPanel.getCurrentObject()) then
(
(gw.wText tris_line_pos (getNumFacesAsString $) color:[255,199,71])
global_line_pos += line_height
)
else
(
gw.wText edges_line_pos (getNumEdgesAsString $) color:[255,199,71]
global_line_pos += line_height
)
gw.wText global_line_pos (getSceneFacesAsString()) color:[165,165,165]
grid_line_pos += (line_height)*3
gw.wText grid_line_pos (gridSize()) color:[165,165,165]
)
4:
(
gw.wText tris_line_pos (getNumFacesAsString $) color:[255,199,71]
global_line_pos += line_height
gw.wText global_line_pos (getSceneFacesAsString()) color:[165,165,165]
grid_line_pos += (line_height)*3
gw.wText grid_line_pos (gridSize()) color:[165,165,165]
)
5:
(
gw.wText tris_line_pos (getNumFacesAsString $) color:[255,199,71]
global_line_pos += line_height
gw.wText global_line_pos (getSceneFacesAsString()) color:[165,165,165]
grid_line_pos += (line_height)*3
gw.wText grid_line_pos (gridSize()) color:[165,165,165]
)
)
gw.enlargeUpdateRect #whole
gw.updateScreen()
)
else
(
gw.wText none_line_pos (none()) color:[255,199,71]
global_line_pos += line_height
gw.wText global_line_pos (getSceneFacesAsString()) color:[165,165,165]
grid_line_pos += (line_height)*3
gw.wText grid_line_pos (gridSize()) color:[165,165,165]
gw.enlargeUpdateRect #whole
gw.updateScreen()
)
)
else
(
gw.wText none_line_pos (none()) color:[255,199,71]
global_line_pos += line_height
gw.wText global_line_pos (getSceneFacesAsString()) color:[165,165,165]
grid_line_pos += (line_height)*3
gw.wText grid_line_pos (gridSize()) color:[165,165,165]
gw.enlargeUpdateRect #whole
gw.updateScreen()
)
)
function startDrawInfo =
(
unregisterRedrawViewsCallback drawInfo
registerRedrawViewsCallback drawinfo
drawInfo()
forceCompleteRedraw()
)
startDrawInfo()
)
It looks correct, but the problem is that the viewport redraw become lagging, like the text flickering when I do anything on the viewport. My maxscript knowledge is very limited so I have no idea how to improve the performance here, could anyone take a look and give some suggestion on how to improve this?
PS; I'm using Max 2009 at home, but in office using Max 2014 I don't think I remember any flickering issue, need to double confirm on this next Monday.
Replies
About the code:
this creates copy(in the memory) of the object each time when it is executed. In the same loop it is used twice. The same is valid for
every xxxx.mesh.yyyy. And it is executed on each viewport redraw several times. For scene with several low poly objects this may not affet the performance, but....
( unregisterRedrawViewsCallback ::drawInfo local stringFormat = (dotNetClass "System.String").Format local lineHeight = (getTextExtent #I).y + 2 local yellowish = color 255 199 71 local grayish = color 165 165 165 function none = case selection.count of ( 0 : "None Selected" 1 : $.name default : "Multiple Selected" ) function getSceneFacesAsString = ( local totalFaces = 0 local selectedFaces = 0 for obj in geometry where isDeformable obj do ( totalFaces += obj.numFaces if obj.isSelected do selectedFaces += obj.numFaces ) stringFormat "GL: {0:n0} ({1:n0})" totalFaces selectedFaces ) function getNumVertsAsString obj = stringFormat "Verts: {0:n0} ({1:n0})" (numPoints obj) obj.selectedVerts.count function getNumEdgesAsString obj = stringFormat "Edges: {0:n0} ({1:n0})" obj.edges.count obj.selectedEdges.count function getNumFacesAsString obj = stringFormat "Faces: {0:n0} ({1:n0})" obj.numFaces obj.selectedFaces.count function isValidObject obj = isKindOf obj Editable_Poly or isKindOf obj Editable_Mesh function isMesh obj = isKindOf obj Editable_Mesh function gridSize = "Grid: " + units.formatValue (if activeGrid == undefined then gridPrefs.spacing else activeGrid.grid) function getTextLocation textExt winSizeX winSizeY lineMult = [winSizeX - textExt - 10, winSizeY - 40 + lineHeight * lineMult, 0] function getTextBox winSizeX winSizeY textExt = Box2 [winSizeX - textExt - 10, winSizeY - 40 + lineHeight * 2] [winSizeX, winSizeY] function redrawRectangle subObjsStr globalCountStr gridSizeStr = ( local winSizeX = gw.getWinSizeX() local winSizeY = gw.getWinSizeY() local subObjsStrExt = (getTextExtent subObjsStr).x local globalCountStrExt = (getTextExtent globalCountStr).x local gridSizeStrExt = (getTextExtent gridSizeStr).x gw.wText (getTextLocation subObjsStrExt winSizeX winSizeY -1) subObjsStr color:yellowish gw.wText (getTextLocation globalCountStrExt winSizeX winSizeY 0) globalCountStr color:grayish gw.wText (getTextLocation gridSizeStrExt winSizeX winSizeY 2) gridSizeStr color:grayish gw.enlargeUpdateRect (getTextBox winSizeX winSizeY (amax subObjsStrExt globalCountStrExt gridSizeStrExt)) gw.updateScreen() ) function drawInfo = ( local obj = modPanel.getCurrentObject() if subObjectLevel != undefined and subObjectLevel > 0 and isValidObject obj then ( case subObjectLevel of ( 1: redrawRectangle (getNumVertsAsString $) (getSceneFacesAsString()) (gridSize()) 2: redrawRectangle (getNumEdgesAsString $) (getSceneFacesAsString()) (gridSize()) 3: ( if isMesh obj then redrawRectangle (getNumFacesAsString $) (getSceneFacesAsString()) (gridSize()) else redrawRectangle (getNumEdgesAsString $) (getSceneFacesAsString()) (gridSize()) ) 4: redrawRectangle (getNumFacesAsString $) (getSceneFacesAsString()) (gridSize()) 5: redrawRectangle (getNumFacesAsString $) (getSceneFacesAsString()) (gridSize()) ) ) else redrawRectangle (none()) (getSceneFacesAsString()) (gridSize()) ) function startDrawInfo = ( registerRedrawViewsCallback ::drawInfo setNeedsRedraw() ) startDrawInfo() )@Swordslayer - wow! you really trim down the code! thanks!..but I notice that if I use; ..the display will gone when I do anything with the viewport but if I replace with "gw.enlargeUpdateRect #whole" it'll stay there. Any reason for this such behavior?
But it clearly that your code make run run much more smoothly despite the constant flickering. Tested with a mesh around 1mil tris, the viewport didnt suffer with a slowdown as much as the previous code I wrote. It seems like related to miauu's point regarding the code creates a copy on a memory. Thanks so much!
Sorry about that, looks like that doesn't have any effect in nitrous.
If you don't mind the polygon count you don't need to loop through all objects. You can just access the mesh totals from fileProperties.
If you do want triangle counts keep in mind you don't need to access the .mesh property for vertex and edge totals.
A while back when I created a viewport callback script I skipped calculations while the mouse was moving and a mouse button was pressed. This allowed the user to pan / orbit the view at full speed.
@monster - yeah, you're right. I do want to display tris instead of polys so I added back .mesh for tris count. That's interesting idea to read only on mouse move, I tried to use mouse.mode since on the help file said; 0-idle, 1-point, 2-move, but no matter what I check (and move my mouse like crazy) while execute the script from the listener, it still return 0 (which means idle?), so how do you check that?
Vertex/edge counters return 0 for me only for the 'selected' subobjects when Show End Result is toggled on (which is to be expected since you are getting the top result of the stack).
By the way, since you are using .mesh once again, save the .mesh to a variable, get your stats and delete it afterwards.
As for the mouse moving or not, you can save mouse position and check if it changed since the last time.
About the count being 0, I guess I can live with that, since the default Max's own statistic (default hotkey:7) also showed 0 when there is a modifier ontop.
Eh? saving the .mesh as a variable? you mean like assigning; ..and use the numFace instead? wasn't too sure tough, better to confirm with you first before putting some junk code into my script
About the mouse position, I seems like can't get anything working, what miauu suggest to use mouse.buttonStates always return #{} or once I got #{3}. I found a really primitive way to check whether mouse is moving of not by declaring 3 variables; ..so basically mouseInitPos will be a static number (initial position) and mouseNewPos will be the dynamic number (new moved position) and compare between the two, when mouse idle it'll return true, when moving will return false. So the problem is....where should I sneak it in?...man! scripting is so addicting!haha
mesh to a variable like this and you call _mesh instead of $.mesh you usually do this when you want to call the same thing more than once...
About assigning the $.mesh into a _mesh variable, is there any benefit by doing so? And I notice if using .mesh for an edge, it will return "wrong" value since 1 quad have 5 edges in mesh (instead of 4 in poly).
( local t = Teapot segments:64 for i = 1 to 1000 do t.mesh.verts.count )and now compare it to
( local t = Teapot segments:64 local m -- one variable to hold them all, outside the loop/functions for i = 1 to 1000 do ( m = t.mesh m.verts.count delete m ) )The other things like checking mouse position.. well, I've taken the liberty to bend the code to fit that purpose once again, I'm not that good with explaining:
( unregisterRedrawViewsCallback ::drawInfo local stringFormat = (dotNetClass "System.String").Format local lineHeight = (getTextExtent #I).y + 2 local meshInfo local meshObj local prevPos struct meshInfoDef ( yellowish = color 255 199 71, grayish = color 165 165 165, winSizeX, winSizeY, textBox, lineSub = dataPair(), lineTotal = dataPair(), lineGrid = dataPair(), function getTextLocation textExt winSizeX winSizeY lineMult = [winSizeX - textExt - 10, winSizeY - 40 + lineHeight * lineMult, 0], function getTextBox winSizeX winSizeY textExt = Box2 [winSizeX - textExt - 10, winSizeY - 40 - lineHeight * 2] [winSizeX, winSizeY], function update subObjsStr globalCountStr gridSizeStr = ( local subObjsStrExt = (getTextExtent subObjsStr).x local globalCountStrExt = (getTextExtent globalCountStr).x local gridSizeStrExt = (getTextExtent gridSizeStr).x local winSizeX = gw.getWinSizeX() local winSizeY = gw.getWinSizeY() textBox = getTextBox winSizeX winSizeY (amax subObjsStrExt globalCountStrExt gridSizeStrExt) lineSub.v1 = getTextLocation subObjsStrExt winSizeX winSizeY -1 lineTotal.v1 = getTextLocation globalCountStrExt winSizeX winSizeY 0 lineGrid.v1 = getTextLocation gridSizeStrExt winSizeX winSizeY 2 lineSub.v2 = subObjsStr lineTotal.v2 = globalCountStr lineGrid.v2 = gridSizeStr ), function redraw = ( gw.wText lineSub.v1 lineSub.v2 color:yellowish gw.wText lineTotal.v1 lineTotal.v2 color:grayish gw.wText lineGrid.v1 lineGrid.v2 color:grayish gw.enlargeUpdateRect textBox gw.updateScreen() ) ) function none = case selection.count of ( 0 : "None Selected" 1 : $.name default : "Multiple Selected" ) function getSceneTrisAsString = ( local totalFaces = 0 local selectedFaces = 0 for obj in geometry where not isKindOf obj TargetObject do ( meshObj = obj.mesh totalFaces += meshObj.numFaces if obj.isSelected do selectedFaces += meshObj.numFaces delete meshObj ) stringFormat "GL: {0:n0} ({1:n0})" totalFaces selectedFaces ) function getNumVertsAsString obj = stringFormat "Verts: {0:n0} ({1:n0})" (numPoints obj) obj.selectedVerts.count function getNumEdgesAsString obj = stringFormat "Edges: {0:n0} ({1:n0})" obj.edges.count obj.selectedEdges.count function getNumTrisAsString obj = ( meshObj = obj.mesh local numTrisStr = stringFormat "Tris: {0:n0} ({1:n0})" meshObj.numFaces meshObj.selectedFaces.count delete meshObj numTrisStr ) function isValidObject obj = isKindOf obj Editable_Poly or isKindOf obj Editable_Mesh function isMesh obj = isKindOf obj Editable_Mesh function gridSize = "Grid: " + units.formatValue (if activeGrid == undefined then gridPrefs.spacing else activeGrid.grid) function drawInfo = ( local pos = mouse.screenPos if pos != prevPos do ( local obj = modPanel.getCurrentObject() if subObjectLevel != undefined and subObjectLevel > 0 and isValidObject obj then ( case subObjectLevel of ( 1: meshInfo.update (getNumVertsAsString $) (getSceneTrisAsString()) (gridSize()) 2: meshInfo.update (getNumEdgesAsString $) (getSceneTrisAsString()) (gridSize()) 3: ( if isMesh obj then meshInfo.update (getNumTrisAsString $) (getSceneTrisAsString()) (gridSize()) else meshInfo.update (getNumEdgesAsString $) (getSceneTrisAsString()) (gridSize()) ) 4: meshInfo.update (getNumTrisAsString $) (getSceneTrisAsString()) (gridSize()) 5: meshInfo.update (getNumTrisAsString $) (getSceneTrisAsString()) (gridSize()) ) ) else meshInfo.update (none()) (getSceneTrisAsString()) (gridSize()) prevPos = pos ) meshInfo.redraw() ) function startDrawInfo = ( meshInfo = meshInfoDef() registerRedrawViewsCallback ::drawInfo setNeedsRedraw() ) startDrawInfo() )Basically, save everything to a struct, redraw with each viewport redraw, update only when mouse positon changes.
Another thing is, isit save to add forceCompleteRedraw() inside the drawInfo function? since currently the text will overlap each other before viewport redraw?
I'm sorry man...I just....I just a little bit OCD when it comes about UI....
About max handling heavy object will slow down viewport, I guess it's just max being...max...hmm...
Couldn't do all this without your help Swordslayer, thanks so much
Watch this video to see which is better to be used.
I google around for a solution before and found something like this;
rollout click_test "Click Test" ( timer tick_tock interval:100 active:true label lbl_button "Idle State" local dnc_control local mouseButtonStates local leftBtn local midBtn local rightBtn local idleState on tick_tock tick do ( mouseButtonStates = dnc_control.MouseButtons.value__ theButtonStr = "" if (dotnet.CompareEnums mouseButtonStates leftBtn) do (idleState = true) if (dotnet.CompareEnums mouseButtonStates midBtn) do (idleState = true) if (dotnet.CompareEnums mouseButtonStates rightBtn) do (idleState = true) if idleState == true then ( lbl_button.text = "Idle State" idleState = false ) else ( lbl_button.text = "" ) ) on click_test open do ( dnc_control = dotNetClass "Control" mouseButtons = dnc_control.MouseButtons leftBtn = mouseButtons.Left.value__ midBtn = mouseButtons.Middle.value__ rightBtn = mouseButtons.Right.value__ ) ) createDialog click_test..not sure is it possible to use this on the code or not, if possible we need to implement it when "Idle State" is displayed, hold the redraw (which basically whenever any one of the mouse button pressed, hold the redraw). Just throwing some idea( ::drawInfoNodeCallback = undefined unregisterRedrawViewsCallback ::drawInfo local stringFormat = (dotNetClass "System.String").Format local lineHeight = (getTextExtent #I).y + 2 local meshInfo local meshObj struct meshInfoDef ( yellowish = color 255 199 71, grayish = color 165 165 165, winSizeX, winSizeY, textBox, lineSub = dataPair(), lineTotal = dataPair(), lineGrid = dataPair(), function getTextLocation textExt winSizeX winSizeY lineMult = [winSizeX - textExt - 10, winSizeY - 40 + lineHeight * lineMult, 0], function getTextBox winSizeX winSizeY textExt = Box2 [winSizeX - textExt - 10, winSizeY - 40 - lineHeight * 2] [winSizeX, winSizeY], function update subObjsStr globalCountStr gridSizeStr = ( local subObjsStrExt = (getTextExtent subObjsStr).x local globalCountStrExt = (getTextExtent globalCountStr).x local gridSizeStrExt = (getTextExtent gridSizeStr).x local winSizeX = gw.getWinSizeX() local winSizeY = gw.getWinSizeY() textBox = getTextBox winSizeX winSizeY (amax subObjsStrExt globalCountStrExt gridSizeStrExt) lineSub.v1 = getTextLocation subObjsStrExt winSizeX winSizeY -1 lineTotal.v1 = getTextLocation globalCountStrExt winSizeX winSizeY 0 lineGrid.v1 = getTextLocation gridSizeStrExt winSizeX winSizeY 2 lineSub.v2 = subObjsStr lineTotal.v2 = globalCountStr lineGrid.v2 = gridSizeStr ), function redraw = ( gw.wText lineSub.v1 lineSub.v2 color:yellowish gw.wText lineTotal.v1 lineTotal.v2 color:grayish gw.wText lineGrid.v1 lineGrid.v2 color:grayish gw.enlargeUpdateRect textBox gw.updateScreen() ) ) function none = case selection.count of ( 0 : "None Selected" 1 : $.name default : "Multiple Selected" ) function getSceneTrisAsString = ( local totalFaces = 0 local selectedFaces = 0 for obj in geometry where not isKindOf obj TargetObject do ( meshObj = obj.mesh totalFaces += meshObj.numFaces if obj.isSelected do selectedFaces += meshObj.numFaces delete meshObj ) stringFormat "GL: {0:n0} ({1:n0})" totalFaces selectedFaces ) function getNumVertsAsString obj = stringFormat "Verts: {0:n0} ({1:n0})" (numPoints obj) obj.selectedVerts.count function getNumEdgesAsString obj = stringFormat "Edges: {0:n0} ({1:n0})" obj.edges.count obj.selectedEdges.count function getNumTrisAsString obj = ( meshObj = obj.mesh local numTrisStr = stringFormat "Tris: {0:n0} ({1:n0})" meshObj.numFaces meshObj.selectedFaces.count delete meshObj numTrisStr ) function isValidObject obj = isKindOf obj Editable_Poly or isKindOf obj Editable_Mesh function isMesh obj = isKindOf obj Editable_Mesh function gridSize = "Grid: " + units.formatValue (if activeGrid == undefined then gridPrefs.spacing else activeGrid.grid) function drawInfo updated:false = ( if updated do ( local obj = modPanel.getCurrentObject() if subObjectLevel != undefined and subObjectLevel > 0 and isValidObject obj then ( case subObjectLevel of ( 1: meshInfo.update (getNumVertsAsString $) (getSceneTrisAsString()) (gridSize()) 2: meshInfo.update (getNumEdgesAsString $) (getSceneTrisAsString()) (gridSize()) 3: ( if isMesh obj then meshInfo.update (getNumTrisAsString $) (getSceneTrisAsString()) (gridSize()) else meshInfo.update (getNumEdgesAsString $) (getSceneTrisAsString()) (gridSize()) ) 4: meshInfo.update (getNumTrisAsString $) (getSceneTrisAsString()) (gridSize()) 5: meshInfo.update (getNumTrisAsString $) (getSceneTrisAsString()) (gridSize()) ) ) else meshInfo.update (none()) (getSceneTrisAsString()) (gridSize()) ) meshInfo.redraw() ) function updateDrawInfo evnt arg = drawInfo updated:true function startDrawInfo = ( meshInfo = meshInfoDef() registerRedrawViewsCallback ::drawInfo ::drawInfoNodeCallback = NodeEventCallback mouseUp:true all:updateDrawInfo drawInfo updated:true setNeedsRedraw() ) startDrawInfo() )Hmmm...now it seems like too less redraw, when selecting subobject even after I mouse up, it still didn't redraw the new number until I pan/rotate/zoom the viewport, tested on Max 2014. How is it on your end?
EDIT: Play with it a little bit more, by adding a completeRedraw() below meshInfo.redraw(), makes it better
Was thinking of using it something like this;
global glRevelTemp ( struct stRevelTemp ( fn mouseBtn = ( timer tick_tock interval:100 active:true local dnc_control local mouseButtonStates local leftBtn, midBtn, rightBtn local leftClicked, midClicked, rightClicked on tick_tock tick do ( mouseButtonStates = dnc_control.MouseButtons.value__ if (dotnet.CompareEnums mouseButtonStates leftBtn) do (leftClicked = true) if (dotnet.CompareEnums mouseButtonStates midBtn) do (midClicked = true) if (dotnet.CompareEnums mouseButtonStates rightBtn) do (rightClicked = true) case of ( (leftClicked == true): (print "left"; leftClicked = false; return #left) (midClicked == true): (print "mid"; midClicked = false; return #mid) (rightClicked == true): (print "right"; rightClicked = false; return #right) ) ) on ??? do ( dnc_control = dotNetClass "Control" mouseButtons = dnc_control.MouseButtons leftBtn = mouseButtons.Left.value__ midBtn = mouseButtons.Middle.value__ rightBtn = mouseButtons.Right.value__ ) ) ) glRevelTemp = stRevelTemp() )..so intended to use it as glRevelTemp.mouseBtn() and return either #left/ #mid/ #right...but the "???" obviously stop the code from being any useful...