First of all filter fn need to be changed
fn filtGroup o = isGroupMember o or isGroupHead o
I was thinking that it might be better and faster to:
– collect all group instance transform.
– attach selection to picked root group
– delete another instances
– copy root group to previous groups positions
But there is a small problem
what if group members of deleted instances have different materials then root group members?
why do you have to care of it? your code makes an instance of selection, attaches it to destination group… that’s it.
I haved trouble with rotation of selection before attach operation. That’s why I use only position alignement. Can you provide some transform (matrix) solution. I’m bad in that area
that’s actually easy… get cloning node’s transform in the picked group coordinate system
tm = node.transform*(inverse <picked group>.transform)
but cloned node has to be returned in the destination group transform
clone.transform = tm*<destination group>.transform
This works very well
try(destroyDialog ::bgaRoll)catch()
rollout bgaRoll " "
(
fn filtGroup o = isGroupMember o or isGroupHead o
fn getRootGroupHead node = if isgroupmember node do
(
while node != undefined and (not isgrouphead node or isgroupmember node) do (node = node.parent)
node
)
pickbutton pick "PickGroup" pos:[5,5] width:100 height:20 filter:filtGroup
on pick picked obj do if obj != undefined and selection.count !=0 do
(
local rootGroup = getRootGroupHead obj
InstanceMgr.GetInstances rootGroup &groups
selObjs = getCurrentSelection()
if groups.count > 1 then
(
with redraw off
(
for i = 1 to groups.count where groups[i] != rootGroup do
(
-- next line not works
--maxOps.cloneNodes selObjs expandHierarchy:on cloneType:#instance newNodes:&objs
maxOps.cloneNodes selObjs cloneType:#instance newNodes:&objs
for o in objs do
(
--next line is need to be removed vhen you try cloning with expandHierarchy:on
if o.parent != undefined do o.parent = undefined
tm = o.transform * (inverse rootGroup.transform)
o.transform = tm*groups[i].transform
attachNodesToGroup o groups[i]
)
)
attachNodesToGroup selObjs rootGroup
)
)
)
)
createDialog bgaRoll 110 30 10 110 style:#(#style_titlebar, #style_sysmenu, #style_toolwindow)
Using “expandHierarchy:on” not works. I think that is not realy inportant in this case.
as i said the transform issue is a simple part of this task. most complicated one is to identify which node (and its hierarchy) can be attached to a group
No doupt. This is very cool. That’s why I must ask you. You are the math genius:bowdown:
Thanks again.
Hey Mike wake up and try2script this
that’s great! I woke up at 9:00 am today!
It’s working when adding a single object, but it doesn’t when adding a group of object to group instances!
>> MAXScript Rollout Handler Exception:
– Runtime error: attachNodesToGroup() failed due to invalid input <<
line – attachNodesToGroup o groups[i]
If I disable this line: attachNodesToGroup o groups[i]
then I get elements of added groups spread throughout all the scene but not on the tables!
Still confusing!
maxOps.cloneNodes selObjs cloneType:#instance newNodes:&objs
for o in objs do
(
if o.parent != undefined do o.parent = undefined
tm = o.transform * (inverse rootGroup.transform)
o.transform = tm*groups[i].transform
--attachNodesToGroup o groups[i]
)
obs here are the groups that where cloned! But I don’t know how to apply next to every object inside every group! Just try to apply this script to the max scene I’ve uploaded on previous page!
I’ve just found
print objs
for o in objs do
(
--next line is need to be removed vhen you try cloning with expandHierarchy:on
-- if o.parent != undefined do o.parent = undefined
if not isGroupHead o then
(
tm = o.transform * (inverse rootGroup.transform)
o.transform = tm*groups[i].transform
)
--attachNodesToGroup o groups[i]
)
But now I have just to –attachNodesToGroup o groups[i]
I prepare new test scene and of course working script.
Select all items on the table and use script by selecting table below.
For the items I used 3 groups and 3 linked objects to make this example mor interesting.
try(destroyDialog ::bgaRoll)catch()
rollout bgaRoll " "
(
fn filtGroup o = (isGroupMember o or isGroupHead o)
fn getRootGroupHead node = if filtGroup node do
(
while node != undefined and (not isgrouphead node or isgroupmember node) do (node = node.parent)
node
)
fn RemoveFrom theArray Itmes = if theArray.count > 0 and Itmes.count > 0 do
(
local idxs = sort (for i in Itmes where (idx = findItem theArray i) > 0 collect idx)
if idxs.count > 0 do for x = idxs.count to 1 by -1 do (deleteItem theArray idxs[x])
theArray
)
fn collectRootGroups arr =
(
local rootGArr = #()
while arr.count != 0 do
(
append rootGArr (getRootGroupHead arr[1])
RemoveFrom arr (join #() rootGArr[rootGArr.count])
) ; rootGArr
)
fn unparentAndClose arr = if arr.count != 0 do
(
for i in arr do
(
if isGroupHead i and isOpenGroupHead i do setGroupOpen i off
i.parent = null
) ; arr
)
fn redefineSelection arr =
(
local groupArr = for o in arr where filtGroup o collect o
arr = RemoveFrom arr groupArr
groupArr = collectRootGroups groupArr
arr = unparentAndClose (join arr groupArr)
)
pickbutton pick "PickGroup" pos:[5,5] width:100 height:20 filter:filtGroup
on pick picked obj do if obj != undefined and selection.count !=0 do
(
local selObjs = redefineSelection (getCurrentSelection())
local rootGroup = getRootGroupHead obj
InstanceMgr.GetInstances rootGroup &groups
if groups.count > 1 then
(
with redraw off
(
for i = 1 to groups.count where groups[i] != rootGroup do
(
maxOps.cloneNodes selObjs cloneType:#instance newNodes:&objs
for o in (redefineSelection objs) do
(
tm = o.transform * (inverse rootGroup.transform)
o.transform = tm*groups[i].transform
attachNodesToGroup o groups[i]
)
)
attachNodesToGroup selObjs rootGroup
)
)
)
)
createDialog bgaRoll 110 30 10 110 style:#(#style_titlebar, #style_sysmenu, #style_toolwindow)
try the sample scene from try2script.
you script doesn’t work right for it. you are doing a lot of unnecessary things (most are about opened groups)… the only function that you need for cloned selection is the function that returns only highest by hierarchy nodes. after that you have to clone only them with their children if the ‘root’ node is not a group member.
so you need three simple functions:
fn getRoot node nodes: = ...
fn getRootNodes nodes: = ...
mapped fn attachNodeToAllGroupInstances node group includeChildren:#all = ...
and this will be a line to call:
attachNodeToAllGroupInstances (getRootNodes nodes:(selection as array)) <group> includeChildren:#all