Outliner上の順番を整理したい 2


https://qiita.com/9boz/items/c78177d5d537c4ff1cca

前回の課題

- 部分的にソートとかしたい

をやってみようかと思います。

設計
-

https://help.autodesk.com/cloudhelp/2022/JPN/Maya-Tech-Docs/CommandsPython/reorder.html

任意の位置に移動させたいので、relativeオプションを使うことになるのかな？

分かり易くやるとすると、relative（相対）と言いつつも先頭を基準とすることでabsolute (絶対)として動かすようにしてみますか。

なので
- 選択しているオブジェクトの階層内の位置(A)を取得
- 整理対象のオブジェクトを順番に　先頭に移動 -> A + n に移動を繰り返す

やってみる
-

サンプル作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/51b26569-9d83-5184-1d2d-a2ede2044cc4.png)

AHogeたちだけをソート

- 選択しているオブジェクトの階層内の位置(A)を取得

いきなりですが
選択順によっては　1つ目 = 先頭　とならない場合がありそうなので
**対象のオブジェクトのなかで1番若い位置(A)を取得**
に変えた方が良い気がしてきました。

階層内の位置は
listRelatives　で親ノードを取得して、
listRelatives　で同一階層のノードを取得すれば取れるかな？

親ノードが無い場合は
cmds.ls(assemblies =True)　とかでいけるかな・・・

```python

def getStartIndex(targets):
    curIndexList = []

    for target in targets:
        parent = cmds.listRelatives(target, p =True)
    
        if parent == None:
            topNodes = cmds.ls(assemblies =True)
            index = topNodes.index(target)
            curIndexList.append(index)
    
        else:
            nodes = cmds.listRelatives(parent[0],type = "transform")
            index = nodes.index(target)
            curIndexList.append(index)

    curIndexList.sort()
    return curIndexList[0]

```

実行
```
getStartIndex(cmds.ls(sl =True))
# Result: 10 # 
```

10？！　と思ったけどもカメラとか含めると　10でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/5036fb4f-11d3-9084-fbcc-c0f48bfc50a6.png)


- 整理対象のオブジェクトを順番に　先頭に移動 -> A + n に移動を繰り返す

前回作ったやつを改造しますかね

```python
def sortOrder(targets,startIndex = None):
    sortTargets = sorted(targets)

    if startIndex == None:
        for target in sortTargets:
            cmds.reorder(target, b =True)
    else:
        for i in range(0,len(sortTargets)):
            cmds.reorder(sortTargets[i], f =True)
            cmds.reorder(sortTargets[i], relative = startIndex + i)
```

組み合わせて実行
```python
targets = cmds.ls(sl =True)
startIndex = getStartIndex(targets)
sortOrder(targets,startIndex)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/5fc19de6-bef3-fcf7-f915-d4893b7cebf8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1484234/3e9508b5-13d4-fa7f-586e-022898afc58b.png)

上手く行ったかな？

まとめるとこんな感じ
念のため ls では transformノードのみにフィルター

``` python
def getStartIndex(targets):
    curIndexList = []

    for target in targets:
        parent = cmds.listRelatives(target, p =True)
    
        if parent == None:
            topNodes = cmds.ls(assemblies =True)
            index = topNodes.index(target)
            curIndexList.append(index)
    
        else:
            nodes = cmds.listRelatives(parent[0],type = "transform")
            index = nodes.index(target)
            curIndexList.append(index)

    curIndexList.sort()
    return curIndexList[0]

def sortOrder(targets,startIndex = None):
    sortTargets = sorted(targets)

    if startIndex == None:
        for target in sortTargets:
            cmds.reorder(target, b =True)
    else:
        for i in range(0,len(sortTargets)):
            cmds.reorder(sortTargets[i], f =True)
            cmds.reorder(sortTargets[i], relative = startIndex + i)

targets = cmds.ls(sl =True, type = "transform")
startIndex = getStartIndex(targets)
sortOrder(targets,startIndex)

```


まとめ
-

- 作ってみたものの、割と出番は少なそう
- 階層をまたいで選択した場合の対処は必要
- やはり階層内全部整理したい


続く・・・・かも