Fix incorrect connections for muted nodes in tile compositor
[blender.git] / source / blender / compositor / nodes / COM_MuteNode.cpp
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor: 
19  *              Jeroen Bakker 
20  *              Monique Dewanchand
21  */
22
23 #include "COM_MuteNode.h"
24 #include "COM_SocketConnection.h"
25 #include "COM_SetValueOperation.h"
26 #include "COM_SetVectorOperation.h"
27 #include "COM_SetColorOperation.h"
28
29 extern "C" {
30         #include "BLI_listbase.h"
31 }
32
33 MuteNode::MuteNode(bNode *editorNode) : Node(editorNode)
34 {
35         /* pass */
36 }
37
38 void MuteNode::reconnect(ExecutionSystem *graph, OutputSocket *output)
39 {
40         vector<InputSocket *> &inputsockets = this->getInputSockets();
41         for (unsigned int index = 0; index < inputsockets.size(); index++) {
42                 InputSocket *input = inputsockets[index];
43                 if (input->getDataType() == output->getDataType()) {
44                         if (input->isConnected()) {
45                                 output->relinkConnections(input->getConnection()->getFromSocket(), false);
46                                 return;
47                         }
48                 }
49         }
50         
51         NodeOperation *operation = NULL;
52         switch (output->getDataType()) {
53                 case COM_DT_VALUE:
54                 {
55                         SetValueOperation *valueoperation = new SetValueOperation();
56                         valueoperation->setValue(0.0f);
57                         operation = valueoperation;
58                         break;
59                 }
60                 case COM_DT_VECTOR:
61                 {
62                         SetVectorOperation *vectoroperation = new SetVectorOperation();
63                         vectoroperation->setX(0.0f);
64                         vectoroperation->setY(0.0f);
65                         vectoroperation->setW(0.0f);
66                         operation = vectoroperation;
67                         break;
68                 }
69                 case COM_DT_COLOR:
70                 {
71                         SetColorOperation *coloroperation = new SetColorOperation();
72                         coloroperation->setChannel1(0.0f);
73                         coloroperation->setChannel2(0.0f);
74                         coloroperation->setChannel3(0.0f);
75                         coloroperation->setChannel4(0.0f);
76                         operation = coloroperation;
77                         break;
78                 }
79         }
80
81         if (operation) {
82                 output->relinkConnections(operation->getOutputSocket(), false);
83                 graph->addOperation(operation);
84         }
85
86         output->clearConnections();
87 }
88
89 template<class SocketType> void MuteNode::fillSocketMap(vector<SocketType *> &sockets, SocketMap &socketMap)
90 {
91         for (typename vector<SocketType *>::iterator it = sockets.begin(); it != sockets.end(); it++) {
92                 Socket *socket = (Socket *) *it;
93
94                 socketMap.insert(std::pair<bNodeSocket *, Socket *>(socket->getbNodeSocket(), socket));
95         }
96 }
97
98 void MuteNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
99 {
100         bNode *editorNode = this->getbNode();
101         vector<OutputSocket *> &outputsockets = this->getOutputSockets();
102
103         if (editorNode->typeinfo->internal_connect) {
104                 vector<InputSocket *> &inputsockets = this->getInputSockets();
105                 bNodeTree *editorTree = (bNodeTree *) context->getbNodeTree();
106                 SocketMap socketMap;
107                 ListBase intlinks;
108                 bNodeLink *link;
109
110                 intlinks = editorNode->typeinfo->internal_connect(editorTree, editorNode);
111
112                 this->fillSocketMap<OutputSocket>(outputsockets, socketMap);
113                 this->fillSocketMap<InputSocket>(inputsockets, socketMap);
114
115                 for (link = (bNodeLink *) intlinks.first; link; link = link->next) {
116                         if (link->fromnode == editorNode) {
117                                 InputSocket *fromSocket = (InputSocket *) socketMap.find(link->fromsock)->second;
118                                 OutputSocket *toSocket = (OutputSocket *) socketMap.find(link->tosock)->second;
119
120                                 toSocket->relinkConnections(fromSocket->getConnection()->getFromSocket(), false);
121                         }
122                 }
123
124                 BLI_freelistN(&intlinks);
125         }
126         else {
127                 for (unsigned int index = 0; index < outputsockets.size(); index++) {
128                         OutputSocket *output = outputsockets[index];
129                         if (output->isConnected()) {
130                                 reconnect(graph, output);
131                         }
132                 }
133         }
134 }