[ create a new paste ] login | about

Link: http://codepad.org/ne4v1nBN    [ raw code | output | fork ]

Python, pasted on Aug 13:
    # --------------------------------------------------------------------------------------------
    # --- Private methods

    def cloneCopy(self, oldnode, newnode):
        """
        Clone copy a node.
        Copy sub node data like tags and tracks.
        :param oldnode : The old node to dopy from.
        :param newnode : The new node to copy to.
        """
        newnode = newnode.GetClone(c4d.COPYFLAGS_NO_HIERARCHY | c4d.COPYFLAGS_NO_BRANCHES)
        newnode = self.copyData(oldnode, newnode)
        newnode = self.copyNodeData(oldnode, newnode)
        return newnode

    def copyData(self, oldnode, newnode):
        """
        Copy all lowlevel data. (name, global matrix, bits, basecontainer and userdata)
        :param oldnode : The old node to dopy from.
        :param newnode : The new node to copy to.
        """
        # copy matrix
        newnode.SetMg(oldnode.GetMg())
        # copy nbits
        for i in xrange(84):
            if oldnode.GetNBit(i):
                newnode.ChangeNBit(i, c4d.NBITCONTROL_SET)
            else:
                newnode.ChangeNBit(i, c4d.NBITCONTROL_CLEAR)
        # copy bits
        newnode.SetAllBits(oldnode.GetAllBits())
        # copy & convert ids
        newnode[c4d.PRIM_VECTORNULL_OPTIONS_COLOR_MODE] = c4d.PRIM_VECTORNULL_OPTIONS_COLOR_MODE_STATIC
        newnode[c4d.ID_BASELIST_NAME] = oldnode[c4d.ID_BASELIST_NAME]
        newnode[c4d.ID_LAYER_LINK] = oldnode[c4d.ID_LAYER_LINK]
        newnode[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] = oldnode[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR]
        newnode[c4d.ID_BASEOBJECT_VISIBILITY_RENDER] = oldnode[c4d.ID_BASEOBJECT_VISIBILITY_RENDER]
        newnode[c4d.PRIM_VECTORNULL_OPTIONS_ID_COLOR_BASE] = oldnode[c4d.ID_BASEOBJECT_COLOR]
        if oldnode[c4d.NULLOBJECT_DISPLAY] != c4d.NULLOBJECT_DISPLAY_NONE:
            r = oldnode[c4d.NULLOBJECT_RADIUS] * 2
            newnode[c4d.PRIM_VECTORNULL_DRAW_ORIGIN] = True
            newnode[c4d.PRIM_VECTORNULL_ORIGIN_SIZE] = c4d.Vector(r)
            newnode[c4d.PRIM_VECTORNULL_ORIGIN_TYPE] = c4d.PRIM_VECTORNULL_ORIGIN_TYPE_DOT
            if oldnode[c4d.NULLOBJECT_DISPLAY] == c4d.NULLOBJECT_DISPLAY_POINT:
                newnode[c4d.PRIM_VECTORNULL_ORIGIN_TYPE] = c4d.PRIM_VECTORNULL_ORIGIN_TYPE_AXIS
            elif oldnode[c4d.NULLOBJECT_DISPLAY] == c4d.NULLOBJECT_DISPLAY_CIRCLE:
                newnode[c4d.PRIM_VECTORNULL_ORIGIN_TYPE] = c4d.PRIM_VECTORNULL_ORIGIN_TYPE_CIRCLE
            elif oldnode[c4d.NULLOBJECT_DISPLAY] == c4d.NULLOBJECT_DISPLAY_RECTANGLE:
                newnode[c4d.PRIM_VECTORNULL_ORIGIN_TYPE] = c4d.PRIM_VECTORNULL_ORIGIN_TYPE_BOX
            elif oldnode[c4d.NULLOBJECT_DISPLAY] == c4d.NULLOBJECT_DISPLAY_CUBE:
                newnode[c4d.PRIM_VECTORNULL_ORIGIN_TYPE] = c4d.PRIM_VECTORNULL_ORIGIN_TYPE_CUBE
            elif oldnode[c4d.NULLOBJECT_DISPLAY] == c4d.NULLOBJECT_DISPLAY_PYRAMID:
                newnode[c4d.PRIM_VECTORNULL_ORIGIN_TYPE] = c4d.PRIM_VECTORNULL_ORIGIN_TYPE_PYRAMID
            elif oldnode[c4d.NULLOBJECT_DISPLAY] == c4d.NULLOBJECT_DISPLAY_SPHERE:
                newnode[c4d.PRIM_VECTORNULL_ORIGIN_TYPE] = c4d.PRIM_VECTORNULL_ORIGIN_TYPE_SPHERE
            elif oldnode[c4d.NULLOBJECT_DISPLAY] == c4d.NULLOBJECT_DISPLAY_AXIS:
                newnode[c4d.PRIM_VECTORNULL_DRAW_ORIGIN] = False
                newnode[c4d.PRIM_VECTORNULL_DRAW_MATRIX] = True
                newnode[c4d.PRIM_VECTORNULL_MATRIX_AXIS] = True
                newnode[c4d.PRIM_VECTORNULL_MATRIX_X] = True
                newnode[c4d.PRIM_VECTORNULL_MATRIX_Y] = True
                newnode[c4d.PRIM_VECTORNULL_MATRIX_Z] = True
            if oldnode[c4d.NULLOBJECT_ORIENTATION] == c4d.NULLOBJECT_ORIENTATION_SCREEN:
                newnode[c4d.PRIM_VECTORNULL_ORIGIN_PLANE] = c4d.PRIM_VECTORNULL_ORIGIN_PLANE_CAM
            if oldnode[c4d.NULLOBJECT_ORIENTATION] == c4d.NULLOBJECT_ORIENTATION_XY:
                newnode[c4d.PRIM_VECTORNULL_ORIGIN_PLANE] = c4d.PRIM_VECTORNULL_ORIGIN_PLANE_XY
            if oldnode[c4d.NULLOBJECT_ORIENTATION] == c4d.NULLOBJECT_ORIENTATION_ZY:
                newnode[c4d.PRIM_VECTORNULL_ORIGIN_PLANE] = c4d.PRIM_VECTORNULL_ORIGIN_PLANE_ZY
            if oldnode[c4d.NULLOBJECT_ORIENTATION] == c4d.NULLOBJECT_ORIENTATION_XZ:
                newnode[c4d.PRIM_VECTORNULL_ORIGIN_PLANE] = c4d.PRIM_VECTORNULL_ORIGIN_PLANE_XZ
        # copy user data
        for descid, container in oldnode.GetUserDataContainer():
            newnode.SetUserDataContainer(descid, container)
            newnode[descid] = oldnode[descid]
        return newnode

    def copyNodeData(self, oldnode, newnode):
        """
        Copy sub node data like tags and tracks.
        :param oldnode : The old node to dopy from.
        :param newnode : The new node to copy to.
        """
        for tag in reversed(oldnode.GetTags()):
            newnode.InsertTag(tag.GetClone(c4d.COPYFLAGS_0))
        for track in reversed(oldnode.GetCTracks()):
            newnode.InsertTrackSorted(track.GetClone(c4d.COPYFLAGS_0))
        return newnode

    def copyReferences(self, doc, nodelist, clonelist):
        """
        Replace node references in all document nodes.
        :param doc       : The active document.
        :param nodelist  : The list of old nodes to be replaced (in the same order as clonelist).
        :param clonelist : The list of new nodes as the replacment (in the same order as nodelist).
        """
        node = doc.GetFirstObject()
        while (node is not None):
            if node not in nodelist:
                # objects
                data = node.GetDataInstance()
                self.replaceContainerReference(doc, data, node, nodelist, clonelist)
                # tags
                for tag in node.GetTags():
                    data = tag.GetDataInstance()
                    self.replaceContainerReference(doc, data, tag, nodelist, clonelist)
                    # if tag.CheckType(c4d.Texpresso):
                    #     master = tag.GetNodeMaster()
                    #     if isinstance(master, graphview.GvNodeMaster):
                    #         gvnode = master.GetRoot()
                    #         while (gvnode is not None):
                    #             print gvnode
                    #             data = gvnode.GetDataInstance()
                    #             self.replaceContainerReference(doc, data, gvnode, nodelist, clonelist)
                    #             gvnode = self.getNextObject(gvnode)
            node = self.getNextObject(node)

    def getData(self, doc):
        """
        Returns all null objects in the active selection and the first fhVectorNull as the template
        obejct. If there is no selection the whole document is being searched. If there is no fhVectorNull
        found a new instance is returned.
        :param doc : The active document.
        :return    : c4d.Onull[], fhVectorNull
        """
        selection = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_CHILDREN)
        template = None
        nulls = []
        if selection != []:
            for node in selection:
                if node.CheckType(ID_VECTORNULL) and template is None:
                    template = node
                elif node.CheckType(c4d.Onull):
                    nulls.append(node)
        else:
            node = doc.GetFirstObject()
            while (node is not None):
                if node.CheckType(ID_VECTORNULL) and template is None:
                    template = node
                elif node.CheckType(c4d.Onull):
                    nulls.append(node)
                node = self.getNextObject(node)
        if template is None:
            template = c4d.BaseObject(ID_VECTORNULL)
        return nulls, template

    def getNextObject(self, node):
        """
        Get the next object.
        param node : The GeListNode to walk on.
        return     : c4d.GeListNode | None
        """
        if node.GetDown() is not None:
            return node.GetDown()
        while not node.GetNext() and node.GetUp():
            node = node.GetUp()
        return node.GetNext()

    def replaceContainerReference(self, doc, container, node, nodelist, clonelist):
        """
        Method to replace LinkBoxGui and InExcludeData links in basecontainer. Fail-safe
        iteration approach to step over unsopported data-types.
        :param doc       : The active document.
        :param node      : The BaseList2D to take the data from.
        :param nodelist  : The list of old nodes to be replaced (in the same order as clonelist).
        :param clonelist : The list of new nodes as the replacment (in the same order as nodelist).
        """
        # little helper method to be super safe, actually retrieving the id should also work
        # for unknown datatypes.
        def nextid(index):
            try:
                return (index + 1, container.GetIndexId(index + 1))
            except:
                print 'Skipping unsupported datatype for {0}, index: {1}'.format(node, index + 1)
                return nextid(index + 2)
        # step through the container
        index, cid = nextid(-1)
        while (cid != c4d.NOTOK):
            try:
                data = container[cid]
                # baselinks
                if container.GetType(cid) == c4d.DTYPE_BASELISTLINK and data in nodelist:
                    doc.AddUndo(c4d.UNDOTYPE_CHANGE, node)
                    container[cid] = clonelist[nodelist.index(data)]
                    print node, cid, data
                # inexclude
                elif isinstance(data, c4d.InExcludeData):
                    print node, cid, data
                    i, maxid = 0, data.GetObjectCount() - 1
                    while (i < maxid):
                        lstobj = data.ObjectFromIndex(doc, i)
                        print i, lstobj
                        if node is not None and lstobj in nodelist:
                            doc.AddUndo(c4d.UNDOTYPE_CHANGE, node)
                            data.DeleteObject(i)
                            doc.AddUndo(c4d.UNDOTYPE_CHANGE, node)
                            data.InsertObject(clonelist[nodelist.index(data)], 0)
                            i -= 1
                        i += 1
                elif isinstance(data, c4d.BaseContainer):
                    self.replaceContainerReference(doc, data, node, nodelist, clonelist)
            except:
                print 'Skipping unsupported datatype for {0}, container id: {1}'.format(node, cid)
            index, cid = nextid(index)

    def replaceNode(self, doc, oldnode, newnode):
        """
        Replaces the nodes. Returns the new node and deletes the old node.
        Also places places undo steps.
        :param doc     : The active document.
        :param oldnode : The old node to be replaced.
        :param newnode : The new replacment node.
        :return        : c4d.BaseObject
        """
        mg = newnode.GetMg()
        children = oldnode.GetChildren()
        parent = oldnode.GetUp()
        previous = oldnode.GetPred()
        for child in children:
            doc.AddUndo(c4d.UNDOTYPE_CHANGE, child)
            child.InsertUnderLast(newnode)
        doc.AddUndo(c4d.UNDOTYPE_DELETE, oldnode)
        oldnode.Remove()
        if previous is None and parent is not None:
            doc.AddUndo(c4d.UNDOTYPE_CHANGE, newnode)
            newnode.InsertUnder(parent)
        elif previous is not None:
            doc.AddUndo(c4d.UNDOTYPE_CHANGE, newnode)
            newnode.InsertAfter(previous)
        else:
            doc.AddUndo(c4d.UNDOTYPE_CHANGE, newnode)
            doc.InsertObject(newnode)
        newnode.SetMg(mg)
        return newnode

    def run(self, doc):
        """
        Runs the replacement command and palces undo points.
        :param doc : The active docment.
        :return : bool
        """
        # get data
        nodelist, template = self.getData(doc)
        clonelist = []
        temp = c4d.BaseObject(c4d.Onull)
        doc.StartUndo()
        doc.InsertObject(temp)
        doc.AddUndo(c4d.UNDOTYPE_NEW, temp)
        # copy old node qualities to the new nodes
        # and insert the nodes into the docoment at a temp location
        for node in nodelist:
            clone = self.cloneCopy(node, template)
            clonelist.append(clone)
            clone.InsertUnderLast(temp)
            doc.AddUndo(c4d.UNDOTYPE_NEW, clone)
        c4d.EventAdd()
        # overwrite all references the old nodes in the document.
        self.copyReferences(doc, nodelist, clonelist)
        # replace nodes.
        for i, oldnode in enumerate(nodelist):
            self.replaceNode(doc, oldnode, clonelist[i])
        # remove temp
        doc.AddUndo(c4d.UNDOTYPE_DELETE, temp)
        temp.Remove()
        doc.EndUndo()
        c4d.EventAdd()
        return True


Output:
1
2
3
4
  Line 4
    def cloneCopy(self, oldnode, newnode):
    ^
IndentationError: unexpected indent


Create a new paste based on this one


Comments: