ebee1f254551e1a35b332714b4e771c8bf2375eb
[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         createDefaultOutput(graph, output);
52 }
53
54 void MuteNode::createDefaultOutput(ExecutionSystem *graph, OutputSocket *output)
55 {
56         NodeOperation *operation = NULL;
57         switch (output->getDataType()) {
58                 case COM_DT_VALUE:
59                 {
60                         SetValueOperation *valueoperation = new SetValueOperation();
61                         valueoperation->setValue(0.0f);
62                         operation = valueoperation;
63                         break;
64                 }
65                 case COM_DT_VECTOR:
66                 {
67                         SetVectorOperation *vectoroperation = new SetVectorOperation();
68                         vectoroperation->setX(0.0f);
69                         vectoroperation->setY(0.0f);
70                         vectoroperation->setW(0.0f);
71                         operation = vectoroperation;
72                         break;
73                 }
74                 case COM_DT_COLOR:
75                 {
76                         SetColorOperation *coloroperation = new SetColorOperation();
77                         coloroperation->setChannel1(0.0f);
78                         coloroperation->setChannel2(0.0f);
79                         coloroperation->setChannel3(0.0f);
80                         coloroperation->setChannel4(0.0f);
81                         operation = coloroperation;
82                         break;
83                 }
84         }
85
86         if (operation) {
87                 output->relinkConnections(operation->getOutputSocket(), false);
88                 graph->addOperation(operation);
89         }
90
91         output->clearConnections();
92 }
93
94 template<class SocketType> void MuteNode::fillSocketMap(vector<SocketType *> &sockets, SocketMap &socketMap)
95 {
96         for (typename vector<SocketType *>::iterator it = sockets.begin(); it != sockets.end(); it++) {
97                 Socket *socket = (Socket *) *it;
98
99                 socketMap.insert(std::pair<bNodeSocket *, Socket *>(socket->getbNodeSocket(), socket));
100         }
101 }
102
103 void MuteNode::convertToOperations(ExecutionSystem *graph, CompositorContext *context)
104 {
105         bNode *editorNode = this->getbNode();
106         vector<OutputSocket *> &outputsockets = this->getOutputSockets();
107
108         /* mute node is also used for unknown nodes and couple of nodes in fast mode
109          * can't use generic routines in that case
110          */
111         if ((editorNode->flag & NODE_MUTED) && editorNode->typeinfo->internal_connect) {
112                 vector<InputSocket *> &inputsockets = this->getInputSockets();
113                 vector<OutputSocket *> relinkedsockets;
114                 bNodeTree *editorTree;
115                 SocketMap socketMap;
116                 ListBase intlinks;
117                 bNodeLink *link;
118
119                 if (this->getbNodeGroup()) {
120                         editorTree = (bNodeTree *) getbNodeGroup()->id;
121                 } else {
122                         editorTree = (bNodeTree *) context->getbNodeTree();
123                 }
124
125                 intlinks = editorNode->typeinfo->internal_connect(editorTree, editorNode);
126
127                 this->fillSocketMap<OutputSocket>(outputsockets, socketMap);
128                 this->fillSocketMap<InputSocket>(inputsockets, socketMap);
129
130                 for (link = (bNodeLink *) intlinks.first; link; link = link->next) {
131                         if (link->fromnode == editorNode) {
132                                 InputSocket *fromSocket = (InputSocket *) socketMap.find(link->fromsock)->second;
133                                 OutputSocket *toSocket = (OutputSocket *) socketMap.find(link->tosock)->second;
134
135                                 if (toSocket->isConnected()) {
136                                         if (fromSocket->isConnected()) {
137                                                 toSocket->relinkConnections(fromSocket->getConnection()->getFromSocket(), false);
138                                         }
139                                         else {
140                                                 createDefaultOutput(graph, toSocket);
141                                         }
142
143                                         relinkedsockets.push_back(toSocket);
144                                 }
145                         }
146                 }
147
148                 /* in some cases node could be marked as muted, but it wouldn't have internal connections
149                  * this happens in such cases as muted render layer node
150                  *
151                  * to deal with such cases create default operation for not-relinked output sockets
152                  */
153
154                 for (unsigned int index = 0; index < outputsockets.size(); index++) {
155                         OutputSocket *output = outputsockets[index];
156
157                         if (output->isConnected()) {
158                                 bool relinked = false;
159                                 vector<OutputSocket *>::iterator it;
160
161                                 for (it = relinkedsockets.begin(); it != relinkedsockets.end(); it++) {
162                                         if (*it == output) {
163                                                 relinked = true;
164                                                 break;
165                                         }
166                                 }
167
168                                 if (!relinked)
169                                         createDefaultOutput(graph, output);
170                         }
171                 }
172
173                 BLI_freelistN(&intlinks);
174         }
175         else {
176                 for (unsigned int index = 0; index < outputsockets.size(); index++) {
177                         OutputSocket *output = outputsockets[index];
178                         if (output->isConnected()) {
179                                 reconnect(graph, output);
180                         }
181                 }
182         }
183 }