[Closed] MaxSQL
Got a new contraption that got a bit out of hand. It’s a way to get anything from the scene using something that resembles how you would interact with a mysql.database.
Have a look at the examples, I think it’s quiite powerfull, think of it like getClassInstances on steroids! The concept is to build up a query by setting the struct parameters and then _run() it to get the result.
It’s a bit of a polished prototype at the moment so if anyone sees room for improvements feel free to add. I avoided class specific code and or executes. Maybe the lambda functions are a bit messy, if there is a better way let me know!
(be careful if you run this in an existing scene, example #4 renames all things dirived from the texturemap class)
Enjoy!
struct maxSQL
(
private
fn recursive_find_subanim sa out =
(
if (classof sa == subanim) do
(
for i=1 to sa.numSubs do (
if (classof sa[1] == subanim) do
(
appendifunique out sa[i]
out = recursive_find_subanim sa[i] out
)
)
)
out
),
fn recursive_find_inherted_classes _class _trg out =
(
items = refs.dependson _trg
for item in items do
(
tmp=classof item
while (classof tmp != Value AND classof tmp != MaxWrapper ) do
(
if (classof tmp == _class ) do ( append out item; )
tmp=classof tmp
)
out = this.recursive_find_inherted_classes _class item out
)
out
),
fn getInheretedClassInstances _class target:false = ( this.recursive_find_inherted_classes _class target #() ),
public
_select = false,
_from = #(),
_where,
_order = #(),
_set,
_result =#(),
collection,
verbose = false,
fn debug msg = ( if this.verbose do print msg ),
fn _run _select:this._select _from:this._from _where:this._where _order:this._order _set:this._set nocache:false =
(
if (_where == undefined) then ( _where = fn __ item = (true); )
if (classof _from == subanim) do ( _from = this.recursive_find_subanim _from #(); ) -- get all nested sub anims.
if (classof _from != array) do (_from=#(_from))
-- select requested items
collection= #();
if (classof _select != Array ) do ( _select = #(_select))
i=0;
for sel in _select do
(
for src in _from do
(
items = #()
case of
(
( classof sel == ObjectSet ) : ( items = src ) --work with sets of nodes (Objects, Cameras, etc)
( isProperty sel "creatable" == false ) : ( items = this.getInheretedClassInstances sel target:src ) --select instances which are extended from a given 'deeper' class (texturemap, rotationcontroller, etc)
default: items = getClassInstances sel target:src --select a creatable class
)
for item in items where ( _where item items:items i:i ) do ( if (appendifunique collection item) do ( i+=1 ) )
)
)
--Order items
if (_order.count > 0) do
(
if (_order[2]==#desc) then ( _order[2] = 1 ) else (_order[2]=-1)
qsort collection (
fn __ item1 item2 data: = (
a=b=false;
if ( isproperty item1 data[1] ) do ( a=getProperty item1 data[1] )
if ( isproperty item2 data[1] ) do ( b=getProperty item2 data[1] )
if ( a==b ) do ( return 0 );
if ( a>b ) do ( return -1*data[2] )
return 1*data[2]
)
) data:_order;
)
--set properties
if (_set !=undefined) do
(
for i = 1 to collection.count do ( _set collection[i] items:collection i:i )
)
--if allowed cache the latest result in the struct
if (not nocache ) do (this._result = collection)
collection
)
)
( ---- USAGE EXAMPLES -----
print "example 1"
q=maxSQL() -- create new struct
q._select=PRS; -- give me all the PRS controllers
q._from=cameras; --that are in this set of objects
result = q._run() -- run query
print result #nomap
print "---------"
print "example 2"
q=maxSQL() -- create new struct
q._select=bitmaptexture; -- give me all the bitmaptexture instances
q._from=objects ; --that are used on anything in this set of objects
q._where= ( fn __ item = ( not doesfileexist item.fileName )) -- where the file does not exist;
result = q._run() -- run query, you'll get an array with all isntances that have missing bitmaps
print result #nomap
print "---------"
print "example 3"
q=maxSQL() -- create new struct
q._select=texturemap; -- give me all the instances of texturemaps (noise, checker, bitmaptexture etc)
q._from=objects ; --that are used on anything in this set of objects
q._where= ( fn __ item = ( not (classof item == Noise AND item.color1== color 0 0 0 ))) -- but not the noise maps that have a black #1 color
result = q._run()
print result #nomap
print "---------"
print "example 4"
q=maxSQL() -- create new struct
q._select=texturemap; -- give me all the instances of texturemaps (noise, checker, bitmaptexture etc)
q._from=objects ; --that are used on anything in this set of objects
q._order = #( "name", #asc ) -- order them by name ascending ( #desc for the reverse)
--q._set = fn __ item i: = ( item.name = "map_" + i as string; ) -- uncomment to set map names to incremental names.
result = q._run() -- run query, you'll get al maps renamed
print result #nomap
print "---------"
print "example 5"
q=maxSQL() -- create new struct
q._select=material; -- give me anything that is a maxtrix3 conroller
q._from=selection ; --that are used on anything in this set of objects
q._where= ( fn __ item = ( findstring (classof item as string ) "corona" != undefined )) -- that have the 'corona' in their classname
result = q._run() -- run query, you'll get an array with all corona material instances used in the scene
print result #nomap
print "---------"
print "example 6"
q=maxSQL()
--Items from a class or inhereted class we are looking for
q._select=texturemap;
--Array or single item of anything on which hierachy to search in
q._from=objects;
-- a function that take 'item' as parameter. if it returns true the item will be inthe result
q._where = ( fn __ item = ( if (isProperty item "coords" AND classof item.coords == StandardUVGen ) then ( item.coords.U_Offset != 0 or item.coords.V_Offset != 0 ) else (false); ) )
-- a property and a #desc or #asc
q._order = #( "name", #asc )
-- run the query, it will return the result
result = q._run()
-- get the lastest cached result again.
result = q._result
print result
print "reversed:"
--now override the order set in the struct, but keep all the other quaery parameters but don't overwrite teh internal cache.
result = q._run _order:#( "name", #desc) nocache:true
print result
print "---------"
print "example 7"
--get selected items in the SME
q=maxSQL() -- create new struct
q._select=#(texturemap, material);
q._from=trackViewNodes[#sme][sme.activeView] ;
q._where = ( fn __ item = ( a= ((sme.GetView (sme.activeView)).GetNodeByRef item); if isproperty a "selected" then a.selected else false)) --;
result = q._run()
print result #nomap
)
Here is another useful example to get all animated float controllers that are part of the selected object’s transform.
q=maxSQL() -- create new struct
q._select=bezier_float; -- give me all the bezier_float controllers
q._from=#($.transform.controller) ; --that are used on anything in this array
q._where= ( fn __ item = ( item.keys.count > 0 )) -- which does have keys on it.
result = q._run() -- run query, you'll get an array with all animated controllers related to transform
print result #nomap
Updated the code in the OP.
the _where and _set function now have optional params, like so:
q._where = ( fn __ item = ( print item; true ) ) --only use item
q._where = ( fn __ item items: = ( print item; print items.count; true ) ) --use item and all items
q._where = ( fn __ item items: i: = ( print item; print items.count; print i; true ) ) - use item, all items, and current item index
The _select can now be either a sinlge item or an array of classes:
q._select=bezier_float; -- get all float controller
q._select=#(bezier_float, PRS); --get all float and PRS controllers
(do make sure the _where and _set function can handle different classes.
And now also support for _from subanims,
--And inspired by Dave's SME endeavors: get all items in the SME that don't have unique names
q=maxSQL() -- create new struct
q._select=#(texturemap, material );
q._from=trackViewNodes[#sme][sme.activeView] ;
q._where = ( fn __ item items: =
(
check=false;
n="";
if ( isproperty item "name" ) do ( n=getProperty item "name"; );
for chk in items where ( ( chk != item AND (isproperty chk "name" ) AND chk.name == n ) ) do ( check = true; );
check
)
)
result = q._run() -- run query, you'll get an array with all instances with non unique names
print result #nomap
Perhaps you can take some ideas from here:
http://forums.cgsociety.org/showthread.php?t=1438311
Proper docs and link to up-to-date source from my free tools repo: