ブラウザで選択された形状を、指定のパート内に移動する (スクリプト)

ブラウザで選択された形状を指定のパート内に移動させるスクリプトです。
スクリプトでの形状の相対的な位置は、dad(parent)/bro/sis/sonで指定することができます。

ブラウザ上で形状を移動させる場合は「shape.place_parent」「shape.place_brother」「shape.place_sister」「shape.place_child」を使用することになります。
それぞれ現在の位置から相対的に移動させるメソッドになります。

ここでは、ブラウザで選択された形状をtargetPartNameで指定された名前のパート内に移動させるものとします。


scene = xshade.scene()

# 階層リストを取得.
# @param[in]  depth        階層の深さ.
# @param[in]  shape        形状.
# @param[in]  targetShape  対象形状.
# @param[out] posA         階層リストが返る.
def search_shape_position(depth, shape, targetShape, posA):
  if shape.ordinal == targetShape.ordinal:
    return True

  ret = False
  index = 0
  if shape.has_son:
    s =  shape.son
    while s.has_bro:
      s = s.bro
      posA.append(index + 1)
      ret = search_shape_position(depth + 1, s, targetShape, posA)
      if ret:
        break
      posA.pop()
      index = index + 1

  return ret

# 指定の形状を同一パート内に末尾に移動.
def place_last (shape):
  while shape.has_bro:
   shape.place_brother(1)

# 形状を移動.
# @param[in] destPart     移動先のパート.
# @param[in] targetShape  移動元の形状.
def place_shape (destPart, targetShape):
  if destPart == None or destPart.type != 2:
    return
  if destPart.ordinal == targetShape.ordinal:
    return

  # destPart/targetShapeの階層リストを取得.
  posA = []
  search_shape_position(0, scene.shape, destPart, posA)
  posB = []
  search_shape_position(0, scene.shape, targetShape, posB)

  couA = len(posA)
  couB = len(posB)
  if couA == 0 or couB == 0:
    return

  if targetShape.dad.ordinal == destPart.ordinal:
    # targetShapeを同一パート内の末尾に移動.
    place_last(targetShape)
    return

  if couB > couA:
    targetShape.place_parent(couB - couA)
    place_shape(destPart, targetShape)
    return

  if couA == couB:
    cou = 0
    for i in range(couA - 1):
      if posA[i] == posB[i]:
        cou = cou + 1
    if cou == couA - 1:
      i1 = posA[couA - 1]
      i2 = posB[couB - 1]
      if i1 - i2 > 1:
        targetShape.place_brother(i1 - i2 - 1)
      else:
        if i2 - i1 >= 1:
          targetShape.place_sister(i2 - i1)
      targetShape.place_child(1)
      place_last(targetShape)
      return
    else:
      for i in range(couA - 1):
        if posA[couA - 2 - i] != posB[couB - 2 - i]:
          targetShape.place_parent(1)
      place_shape(destPart, targetShape)
      return

  if couA > couB:
    for i in range(couB):
      i1 = posA[i]
      i2 = posB[i]
      if i1 != i2:
        if i + 1 < couB:
          targetShape.place_parent(couB - i - 1)
          place_shape(destPart, targetShape)
          return
        else:
          if i1 - i2 > 1:
            targetShape.place_brother(i1 - i2 - 1)
          else:
            if i2 - i1 >= 1:
              targetShape.place_sister(i2 - i1)
          targetShape.place_child(1)
          place_shape(destPart, targetShape)
          return

# 移動先のパート名.
destPartName = "パート1"
partS = scene.get_shape_by_name(destPartName)
if partS == None or partS.type != 2:
  print "\"" + destPartName + "\"は存在しないかパートではありません。"
else:
  for shape in scene.active_shapes:
    place_shape(partS, shape)

指定の形状の階層リストは、「選択形状の階層リストを取得 (スクリプト)」でのスクリプトを使用しています。

Translate »