Python:Spoonfed - (2-10) 激励选择脚本(搬砖)

https://www.patreon.com/posts/python-spoonfed-31572219

2019年11月15日

利用上一课的选择函数,我们现在可以拼凑出一些脚本(有一些事情我们还没有解释,但应该很容易理解)。以下代码将允许您选择当前所选对象的父对象、顶级对象、同级对象、表兄弟对象或子对象。这些功能的一部分过去已包含在 Cineversity 中,但在这里您可以获取它们,包括源代码。

我们先从Parent的选择开始。PS_SelectObject_Parent.py

python 复制代码
import c4d

def SetActiveObjects(objlist):
    cleared = False
    for obj in objlist:
        if not cleared:
            doc.SetActiveObject(obj, c4d.SELECTION_NEW)
            cleared = True
        else:
            doc.SetActiveObject(obj, c4d.SELECTION_ADD)
            

def main():
    if doc == None: return

    activeObjectList = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_CHILDREN)
    if not activeObjectList: return
    
    newSelection = []
    for obj in activeObjectList:
        if obj.GetUp() != None:
            newSelection += [obj.GetUp()]
        else:
            newSelection += [obj]

    SetActiveObjects(newSelection)
    c4d.EventAdd()


if __name__=='__main__':
    main()

在这里,我们将函数 SetActiveObjects() 添加到 API 中的选择设置函数数量中。由于给定的函数 只能选择一个BaseObject 一次 **,因此我们在这里封装SetActiveObject()**并允许传递整个列表。

唯一的技巧是,我们必须使用标志 SELECTION_NEW 设置第一个对象以清除 以前的 设置其他每个对象 选择,但必须使用SELECTION_ADD 。为此,我们使用一个布尔变量 清除 开始 ,它从False 设置为 True ,并在第一次有机会时 保持True )。 (此后一直

在函数 main() 循环中迭代当前选择 中,我们在for,获取每个对象的直接父对象并将其添加到新选择中。如果没有父对象,则将添加对象本身(本质上保持选中状态)。

newSelection 是一个列表对象。 文字初始化为空列表 它由[ ] 。要添加对象,我们首先通过再次将对象括在方括号中来创建一个列表,其中包含该对象中的一项。 将此迷你列表附加到现有列表 可以使用扩展赋值+=

第二个脚本基本相同,但它不是寻找直接父代,而是寻找最顶层的祖先。这是在 while 循环中完成的: PS_SelectObject_Top.py

python 复制代码
import c4d

def SetActiveObjects(objlist):
    cleared = False
    for obj in objlist:
        if not cleared:
            doc.SetActiveObject(obj, c4d.SELECTION_NEW)
            cleared = True
        else:
            doc.SetActiveObject(obj, c4d.SELECTION_ADD)


def main():
    if doc == None: return

    activeObjectList = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_CHILDREN)
    if not activeObjectList: return

    newSelection = []
    for obj in activeObjectList:
        while obj.GetUp() != None:
            obj = obj.GetUp()
        newSelection += [obj]

    SetActiveObjects(newSelection)
    c4d.EventAdd()


if __name__=='__main__':
    main()

我们不需要额外的情况来包含 obj 请注意,如果没有祖先, 循环 本身。在这种情况下,while 结束 本身在obj 处

如果我们在最初的选择中有两个兄弟姐妹会怎样?难道我们不会为两者获得相同的父级或祖先,并且有一个包含重复元素的列表可供选择吗? -- 确实如此,但没关系:将对象设置为活动 两次 不会产生不良影响,因此我们不需要经历整理重复项的麻烦。PS_SelectObject_Siblings.py

python 复制代码
import c4d

def SetActiveObjects(objlist):
    cleared = False
    for obj in objlist:
        if not cleared:
            doc.SetActiveObject(obj, c4d.SELECTION_NEW)
            cleared = True
        else:
            doc.SetActiveObject(obj, c4d.SELECTION_ADD)


def SelectSiblings(startobj):
    global newSelection
    if startobj == None: return

    newSelection += [startobj]
    obj = startobj
    while obj.GetPred() != None:
        newSelection += [obj.GetPred()]
        obj = obj.GetPred()
    obj = startobj
    while obj.GetNext() != None:
        newSelection += [obj.GetNext()]
        obj = obj.GetNext()


def main():
    global newSelection
    if doc == None: return

    activeObjectList = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_CHILDREN)
    if not activeObjectList: return

    newSelection = []
    for obj in activeObjectList:
        SelectSiblings(obj)

    SetActiveObjects(newSelection)
    c4d.EventAdd()


if __name__=='__main__':
    main()

在第三个脚本(选择最初选定对象的所有同级)中,我们引入了一个新函数 SelectSiblings() 。这将获取一个 BaseObject ,并将该对象本身及其所有同级添加到共享全局列表 newSelection 中。 它通过从参数对象走到列表的前面,然后再次从参数对象走到列表的后面来实现这一点。

我们只调用 SelectSiblings 一次,因此我们可能直接保留该代码而不是函数调用(这种做法也称为 内联代码 )。 函数 但是,分离出SetActiveObjectsSelectSiblings 使代码更清晰、更易于阅读 - 而且,我们可以为最后两个脚本重用相同的结构。PS_SelectObject_Cousins.py

python 复制代码
import c4d

def SetActiveObjects(objlist):
    cleared = False
    for obj in objlist:
        if not cleared:
            doc.SetActiveObject(obj, c4d.SELECTION_NEW)
            cleared = True
        else:
            doc.SetActiveObject(obj, c4d.SELECTION_ADD)


def SelectSiblings(startobj):
    global newSelection
    if startobj == None: return

    newSelection += [startobj]
    obj = startobj
    while obj.GetPred() != None:
        newSelection += [obj.GetPred()]
        obj = obj.GetPred()
    obj = startobj
    while obj.GetNext() != None:
        newSelection += [obj.GetNext()]
        obj = obj.GetNext()


def main():
    global newSelection
    if doc == None: return

    activeObjectList = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_CHILDREN)
    if not activeObjectList: return

    newSelection = []
    for obj in activeObjectList:
        if obj.GetUp() == None:
            SelectSiblings(obj)
        else:
            parent = obj.GetUp()
            while parent.GetPred() != None:
                parent = parent.GetPred()
            while parent != None:
                SelectSiblings(parent.GetDown())
                parent = parent.GetNext()

    SetActiveObjects(newSelection)
    c4d.EventAdd()


if __name__=='__main__':
    main()

第四个脚本不仅选择兄弟姐妹,还选择最初选择的对象的"表兄弟"。在这种情况下,"表兄弟"是父母的兄弟姐妹的子对象。为了找到这些,代码首先上一层,然后从头到尾遍历这一层,将所有节点的所有子节点添加到选择中。如果没有父母,代码只会添加兄弟姐妹。

第五个也是最后一个选择器脚本选择最初选定对象的子对象:PS_SelectObject_Children

python 复制代码
import c4d

def SetActiveObjects(objlist):
    cleared = False
    for obj in objlist:
        if not cleared:
            doc.SetActiveObject(obj, c4d.SELECTION_NEW)
            cleared = True
        else:
            doc.SetActiveObject(obj, c4d.SELECTION_ADD)
            

def main():
    if doc == None: return

    activeObjectList = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_CHILDREN)
    if not activeObjectList: return
    
    newSelection = []
    for obj in activeObjectList:
        if obj.GetUp() != None:
            newSelection += [obj.GetUp()]
        else:
            newSelection += [obj]

    SetActiveObjects(newSelection)
    c4d.EventAdd()


if __name__=='__main__':
    main()

这与 Cinema 4D 的内置功能"选择子项"不同,因为该功能会选择所有依赖子树直至最低级别。相反,脚本仅限于 直接子对象(如果没有子对象,甚至是原始对象)。

我没有包含像 C4D 的"选择子项"(无论如何应该命名为"选择子树")这样的功能,因为该功能已经可用。

一点作业:如果所需的目标对象(父对象、顶级对象、兄弟姐妹、子对象、表兄弟)不可用,则所有五个脚本都会保留最初选择的对象。您可能想要更改该行为,以便不再选择最初选择的对象。在什么情况下这才有意义?这容易实现吗?

相关推荐
web135085886354 分钟前
Python毕业设计选题:基于python的白酒数据推荐系统_django+hive
python·django·课程设计
山山而川粤1 小时前
母婴用品系统|Java|SSM|JSP|
java·开发语言·后端·学习·mysql
云空2 小时前
《解锁 Python 数据分析的强大力量》
python·数据挖掘·数据分析
迷失蒲公英2 小时前
XML与Go结构互转实现(序列化及反序列化)
xml·开发语言·golang
测试盐3 小时前
c++编译过程初识
开发语言·c++
MUTA️3 小时前
专业版pycharm与服务器连接
人工智能·python·深度学习·计算机视觉·pycharm
赖赖赖先生3 小时前
fastadmin 框架 生成qr code 二维码图片,PHP 7.4版本
开发语言·php
xuanfengwuxiang3 小时前
安卓帧率获取
android·python·测试工具·adb·性能优化·pycharm
玉红7774 小时前
R语言的数据类型
开发语言·后端·golang
夜斗(dou)4 小时前
node.js文件压缩包解析,反馈解析进度,解析后的文件字节正常
开发语言·javascript·node.js