Notifications
Clear all
[Closed] Remove instances from array of objects – feedback please
Apr 23, 2019 9:01 pm
So – let’s say a scene contains lots of instances of objects and say you don’t want to loop over already processed objects again and again, what would you do? This is probably a very naive approach but I think it does what I need it to.
Just curious what you all think – any potential problems? Is it not a scalable solution because I’m copying arrays?
(
fn removeInstancesFromArray arr =
(
local objsToProcess = deepCopy arr
for obj in arr where (InstanceMgr.GetInstances obj &instances) > 1 do
(
-- remove all clones except for one from objsToProcess
for clonedObjCount = 2 to instances.count do
(
local index = (findItem objsToProcess instances[clonedObjCount])
if index > 0 then deleteItem objsToProcess index
)
)
objsToProcess
)
fn createTestScene =
(
resetMAXFile()
tp = Teapot()
tp1 = instance tp
tp2 = instance tp
s = Sphere()
s1 = instance s
s2 = instance s
)
createTestScene()
select objects
format "selection as array: %\n" (selection as array)
local arrayWithoutInstances = removeInstancesFromArray (selection as array)
format "arrayWithoutInstances: %\n" arrayWithoutInstances
/*
output:
selection as array: #($Teapot:Teapot001 @ [0.000000,0.000000,0.000000], $Teapot:Teapot002 @ [0.000000,0.000000,0.000000], $Teapot:Teapot003 @ [0.000000,0.000000,0.000000], $Sphere:Sphere001 @ [0.000000,0.000000,0.000000], $Sphere:Sphere002 @ [0.000000,0.000000,0.000000], $Sphere:Sphere003 @ [0.000000,0.000000,0.000000])
arrayWithoutInstances: #($Teapot:Teapot003 @ [0.000000,0.000000,0.000000], $Sphere:Sphere003 @ [0.000000,0.000000,0.000000])
*/
-- now I'm ready to process array of unique objects without going over instances unnecessarily ...
)
2 Replies
Apr 23, 2019 9:01 pm
I have added two functions written by denisT and posted in the forum a while ago.
(
fn removeInstancesFromArray arr =
(
local objsToProcess = deepCopy arr
for obj in arr where (InstanceMgr.GetInstances obj &instances) > 1 do
(
-- remove all clones except for one from objsToProcess
for clonedObjCount = 2 to instances.count do
(
local index = (findItem objsToProcess instances[clonedObjCount])
if index > 0 then deleteItem objsToProcess index
)
)
objsToProcess
)
-- find all instanc and reference objects
function FindInstance n =
(
allInsts = #()
for obj in n do
(
if (InstanceMgr.GetInstances obj &instances) > 1 do
(
if findItem allInsts obj == 0 do
join allInsts instances
)
)
-- remove the parsed object from the instantes list
-- if allInsts.count > 1 do
-- (
-- if (idx = findItem allInsts n) != 0 do
-- (
-- deleteItem allInsts idx
-- )
-- )
--
allInsts
)
-- FInd one of each instance
fn uniqueNodes nodes: =
(
if nodes == unsupplied do nodes = objects as array
local handles = #{}
for node in nodes where not handles[GetHandleByAnim node] collect
(
InstanceMgr.GetInstances node &inst
for i in inst do handles[GetHandleByAnim i] = on
node
)
)
fn createTestScene =
(
resetMAXFile()
tp = Teapot()
tp1 = instance tp
tp2 = instance tp
s = Sphere()
s1 = instance s
s2 = instance s
)
createTestScene()
select objects
format "selection as array: %\n" (selection as array)
-- local arrayWithoutInstances = removeInstancesFromArray (selection as array)
local arrayWithoutInstances = uniqueNodes nodes:(selection as array)
format "arrayWithoutInstances: %\n" arrayWithoutInstances
/*
output:
selection as array: #($Teapot:Teapot001 @ [0.000000,0.000000,0.000000], $Teapot:Teapot002 @ [0.000000,0.000000,0.000000], $Teapot:Teapot003 @ [0.000000,0.000000,0.000000], $Sphere:Sphere001 @ [0.000000,0.000000,0.000000], $Sphere:Sphere002 @ [0.000000,0.000000,0.000000], $Sphere:Sphere003 @ [0.000000,0.000000,0.000000])
arrayWithoutInstances: #($Teapot:Teapot003 @ [0.000000,0.000000,0.000000], $Sphere:Sphere003 @ [0.000000,0.000000,0.000000])
*/
-- now I'm ready to process array of unique objects without going over instances unnecessarily ...
)
Apr 23, 2019 9:01 pm
Thank you! I googled but couldn’t find anything, and I specifically googled for denisT too but didn’t turn up any search results.
This is modifying the criteria for what to collect as it’s going through the loop? Clever