[Closed] Noob: How OO is MaxScript?
I’m just starting my forays into the MaxScript landscape … I’ve grown used to taking an object-oriented approach, though.
Recently, Bobo wrote this macro and posted it on the main 3ds forum:
macroScript GetSelEdgeLength category:"CGTalk"
(
fn getSelEdgesLength =
(
local theObj = modPanel.getCurrentObject()
local theLength = 0
case classof theObj of
(
Editable_Mesh: (
if subObjectLevel == 2 then (
local theEdgeSel = getEdgeSelection selection[1]
local theUsedEdges = #()
for i in theEdgeSel do (
local theVerts = (meshop.getVertsUsingEdge selection[1] i) as array
if findItem theUsedEdges (#(theVerts[1],theVerts[2]) as string) == 0 and findItem theUsedEdges (#(theVerts[2],theVerts[1]) as string) == 0 do (
theLength += distance (getVert selection[1] theVerts[1]) (getVert selection[1] theVerts[2])
append theUsedEdges (theVerts as string)
)
)
#(theLength, theEdgeSel.numberset, theUsedEdges.count)
)
else #(-1,-1,-1)
)
Editable_Poly: (
if subObjectLevel == 2 or subObjectLevel == 3 then (
local theEdgeSel = polyOp.getEdgeSelection selection[1]
for i in theEdgeSel do (
local theVerts = (polyop.getVertsUsingEdge selection[1] i) as array
theLength += distance (polyop.getVert selection[1] theVerts[1]) (polyop.getVert selection[1] theVerts[2])
)
#(theLength, theEdgeSel.numberset, theEdgeSel.numberset)
)
else #(-1,-1,-1)
)
Edit_Poly: (
if subObjectLevel == 2 or subObjectLevel == 3 then (
local theEdgeSel = theObj.getSelection #Edge
for i in theEdgeSel do (
local theVert1 = theObj.GetVertex (theObj.GetEdgeVertex i 1)
local theVert2 = theObj.GetVertex (theObj.GetEdgeVertex i 2)
theLength += distance theVert1 theVert2
)
#(theLength, theEdgeSel.numberset, theEdgeSel.numberset)
)
else #(-1,-1,-1)
)
Mesh_Select: (
if subObjectLevel == 2 then (
local theEdgeSel = getEdgeSelection selection[1] theObj
local theUsedEdges = #()
for i in theEdgeSel do (
local theVerts = (meshop.getVertsUsingEdge selection[1] i) as array
if findItem theUsedEdges (#(theVerts[1],theVerts[2]) as string) == 0 and findItem theUsedEdges (#(theVerts[2],theVerts[1]) as string) == 0 do (
theLength += distance (getVert selection[1] theVerts[1]) (getVert selection[1] theVerts[2])
append theUsedEdges (theVerts as string)
)
)
#(theLength, theEdgeSel.numberset, theUsedEdges.count)
)
else #(-1,-1,-1)
)
Edit_Mesh: (
if subObjectLevel == 2 then (
local theEdgeSel = getEdgeSelection selection[1] theObj
local theUsedEdges = #()
for i in theEdgeSel do (
local theVerts = (meshop.getVertsUsingEdge selection[1] i) as array
if findItem theUsedEdges (#(theVerts[1],theVerts[2]) as string) == 0 and findItem theUsedEdges (#(theVerts[2],theVerts[1]) as string) == 0 do (
theLength += distance (getVert selection[1] theVerts[1]) (getVert selection[1] theVerts[2])
append theUsedEdges (theVerts as string)
)
)
#(theLength, theEdgeSel.numberset, theUsedEdges.count)
)
else #(-1,-1,-1)
)
)--end case
)--end fn
theResult = getSelEdgesLength()
if theResult[2] >= 0 do
(
format "% Selected Edges; % Unique Edges; Generic Units: % , User Units: %
" theResult[2] theResult[3] theResult[1] (units.formatValue theResult[1])
try
(
clipboardClass = dotNetClass "System.Windows.Forms.Clipboard"
if Keyboard.shiftpressed then
clipboardClass.SetText (theResult[1] as string)
else
clipboardClass.SetText (units.formatValue theResult[1])
)catch()
)
)
Having to write a case statement like that would make me feel all jittery: I’d be looking for a polymorphic ‘getEdgeSelection’ method in the ‘Geometry’ superclass/interface, for example. And/or an ‘Edge’ class or somesuch, whatever is going on under the bonnet.
Is MaxScript like this for purely historical reasons, or is there something more fundamental I’m ignorant about? I don’t know anything much about the SDK yet, would that suit someone with my frame of mind better?
Pure Historical Reasons.
EMesh was in Max in 1.0 and when MAXScript was added, it was supported via its own set of methods. Then somebody added better methods in a meshop structs (that do the same and much more). Then in Max 4 and 5, Editable Poly was added and extended twice with methods similar to those in the meshop struct, so potentially it would be possible to support both easily, BUT in the above case, EPoly supports TWO Edge SO Modes (Edge and Border), so I needed a different case for that, and different code for EMesh to deal with the fact edges in EMesh do not exist (!) and each edge is actually doubled. Then Edit_Poly was added in Max 6 and it had its own set of methods exposed.
Basically, MAXScript is a wrapper around the SDK, so all the uglyness of the SDK is often mirrored in it. But MAXScript is much more elegant than the SDK, so if you have written Max plugins before, you should feel like in heaven…
Thanks so much for the reply, Bobo. It really helps to know a little about the ‘landscape’, and how it got there, before committing a lot of time to trial and error. You don’t waste time looking for things which aren’t there! :hmm: