Ok, here’s another version that could work.
This one works with #autoRenameDups, AND hidden layers (as we’re not using #select).
objNameToMerge = getMaxFileObjectNames maxfile
mergedObjNames = #()
mergedObj = #()
for n in objNameToMerge do
(
-- We check if a node with this name already exists or not, if not it won't be renamed.
if (getNodeByName n) != undefined then
n = uniqueName n
append mergedObjNames n
)
mergeMaxFile maxfile objNameToMerge #AutoRenameDups #useSceneMtlDups
for n in mergedObjNames do
(
append mergedObj (getNodeByName n)
)
do it simple… you don’t need any name comparison or search by name. do it by node:
(
delete objects
for k=1 to 5000 do box() -- current scene objects
oldnodes = objects as array
for k=1 to 1000 do dummy() -- merged objects
newnodes = objects as array
t1 = timestamp()
while oldnodes.count > 0 do
(
if isvalidnode oldnodes[1] do
(
k = finditem newnodes oldnodes[1]
if k != 0 do deleteitem newnodes k
)
deleteitem oldnodes 1
)
newnodes.count
format "all nodes:% merged nodes:% time:%
" objects.count newnodes.count (timestamp() - t1)
)
as you can see for 5000 nodes and 1000 merged it takes almost nothing
i don’t remember now why but in some situations i couldn’t use merge with #select option. probably it was something about selection changed notification.
Indeed, nice one denisT, thanks.
For the #select issues, here is the main issue : as soon as an object is in a hidden layer, it’s not selected.
The other issue with using #select is if the selection lock toggle is enabled, it doesn’t allow the selection focus to be passed onto the new objects.
I use the premerge/postmerge node comparison method for this, as we have an multiple instancing system that merges and renames assets in scene.
How about the combination of these two event callback.
#filePreMerge: integer
#sceneNodeAdded: node
Here’s a simpler method I’ve just been using:
(
local filename = (whatever)
local objNames = #(whatever)
-- Collect list of objects in scene before merge:
local preMergeNodes = (objects as array)
-- Merge objects:
mergeMAXFile filename objNames #mergeDups #renameMtlDups #noRedraw
-- Collect objects that weren't in preMergeNodes list:
local mergedNodes = for obj in objects where (appendIfUnique preMergeNodes obj) collect obj
)
This is me de-lurking – I’ve mined this forum for knowledge for many years, I thought I’d might as well get around to actually posting something
here is a test that shows difference of three ‘find merged’ methods:
(
resetmaxfile #noPrompt
seed 0
objs0 = for k=1 to 10000 collect box name:((random 1 10000) as string)
objs1 = for k=1 to 5000 collect box name:((random 1 10000) as string)
select objs1
file = getdir #temp + @"merge_test2.max"
saveNodes objs1 file quiet:on
delete objs1
old = #{}
for obj in objects do append old (getHandleByAnim obj)
mergeMAXFile file #deleteOldDups quiet:on
t1 = timestamp()
m1 = heapfree
--new = for obj in objects where (appendifunique objs0 obj) collect obj
--new = for obj in objects where (finditem objs0 obj) == 0 collect obj
new = for obj in objects where not old[getHandleByAnim obj] collect obj
format ">> objetcs:% merged:% time:% memory:%
" objects.count new.count (timestamp() - t1) (m1 - heapfree)
)
/*
>> #appendifunique objetcs:12543 merged:5000 time:1975 memory:682088L
>> #finditem objetcs:12543 merged:5000 time:1722 memory:683984L
>> #gethandlebyanim objetcs:12543 merged:5000 time:61 memory:692432L
*/
you can see that #appendifunique or #finditem methods give almost the same result.
#gethandlebyanim method is much faster. and difference will be bigger with lager amount of nodes…
but of course all three take just a little of whole merging process time.
Ahaha, denisT, you’re killing me !
Everytime I read you I find a function I’ve never heard before