218 lines
6.9 KiB
C++
218 lines
6.9 KiB
C++
|
/*
|
||
|
* Copyright 2011, Blender Foundation.
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or
|
||
|
* modify it under the terms of the GNU General Public License
|
||
|
* as published by the Free Software Foundation; either version 2
|
||
|
* of the License, or (at your option) any later version.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful,
|
||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
* GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program; if not, write to the Free Software Foundation,
|
||
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
|
*
|
||
|
* Contributor:
|
||
|
* Jeroen Bakker
|
||
|
* Monique Dewanchand
|
||
|
*/
|
||
|
|
||
|
#include "COM_Socket.h"
|
||
|
#include "COM_Node.h"
|
||
|
#include "COM_SocketConnection.h"
|
||
|
#include "COM_ExecutionSystem.h"
|
||
|
|
||
|
InputSocket::InputSocket(DataType datatype) :Socket(datatype) {
|
||
|
this->connection = NULL;
|
||
|
this->resizeMode = COM_SC_CENTER;
|
||
|
}
|
||
|
InputSocket::InputSocket(DataType datatype, InputSocketResizeMode resizeMode) :Socket(datatype) {
|
||
|
this->connection = NULL;
|
||
|
this->resizeMode = resizeMode;
|
||
|
}
|
||
|
|
||
|
InputSocket::InputSocket(InputSocket* from) :Socket(from->getDataType()) {
|
||
|
this->connection = NULL;
|
||
|
this->resizeMode = from->getResizeMode();
|
||
|
}
|
||
|
|
||
|
int InputSocket::isInputSocket() const { return true; }
|
||
|
const int InputSocket::isConnected() const { return this->connection != NULL; }
|
||
|
|
||
|
void InputSocket::setConnection(SocketConnection *connection) {
|
||
|
this->connection = connection;
|
||
|
}
|
||
|
SocketConnection* InputSocket::getConnection() {return this->connection;}
|
||
|
|
||
|
void InputSocket::determineResolution(unsigned int resolution[],unsigned int preferredResolution[]) {
|
||
|
if (this->isConnected()){
|
||
|
this->connection->getFromSocket()->determineResolution(resolution, preferredResolution);
|
||
|
} else {
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DataType InputSocket::convertToSupportedDataType(DataType datatype) {
|
||
|
int supportedDataTypes = getDataType();
|
||
|
if (supportedDataTypes&datatype) {
|
||
|
return datatype;
|
||
|
}
|
||
|
bool candoValue = supportedDataTypes&COM_DT_VALUE;
|
||
|
bool candoVector = supportedDataTypes&COM_DT_VECTOR;
|
||
|
bool candoColor = supportedDataTypes&COM_DT_COLOR;
|
||
|
|
||
|
if (datatype == COM_DT_VALUE) {
|
||
|
if (candoColor) {
|
||
|
return COM_DT_COLOR;
|
||
|
} else if (candoVector) {
|
||
|
return COM_DT_VECTOR;
|
||
|
}
|
||
|
} else if (datatype == COM_DT_VECTOR) {
|
||
|
if (candoColor) {
|
||
|
return COM_DT_COLOR;
|
||
|
} else if (candoValue) {
|
||
|
return COM_DT_VALUE;
|
||
|
}
|
||
|
} else if (datatype == COM_DT_COLOR) {
|
||
|
if (candoVector) {
|
||
|
return COM_DT_VECTOR;
|
||
|
} else if (candoValue) {
|
||
|
return COM_DT_VALUE;
|
||
|
}
|
||
|
}
|
||
|
return this->getDataType();
|
||
|
}
|
||
|
|
||
|
void InputSocket::determineActualDataType() {
|
||
|
/// @note: this method is only called for inputsocket that are not connected.
|
||
|
/// @note: passes COM_DT_COLOR, the convertToSupportedDataType converts this to a capable DataType
|
||
|
this->setActualDataType(this->convertToSupportedDataType(COM_DT_COLOR));
|
||
|
#if 0 // XXX TODO check for proxy node and use output data type?
|
||
|
if (this->getGroupOutputSocket()) {
|
||
|
if (!this->isInsideOfGroupNode()) {
|
||
|
this->getGroupOutputSocket()->determineActualDataType();
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void InputSocket::notifyActualInputType(DataType datatype) {
|
||
|
DataType supportedDataType = convertToSupportedDataType(datatype);
|
||
|
this->setActualDataType(supportedDataType);
|
||
|
this->fireActualDataTypeSet();
|
||
|
}
|
||
|
|
||
|
void InputSocket::fireActualDataTypeSet() {
|
||
|
this->getNode()->notifyActualDataTypeSet(this, this->getActualDataType());
|
||
|
}
|
||
|
void InputSocket::relinkConnections(InputSocket *relinkToSocket) {
|
||
|
this->relinkConnections(relinkToSocket, false, -1, NULL);
|
||
|
}
|
||
|
|
||
|
void InputSocket::relinkConnections(InputSocket *relinkToSocket, bool autoconnect, int editorNodeInputSocketIndex, bool duplicate, ExecutionSystem* graph) {
|
||
|
if (!duplicate) {
|
||
|
this->relinkConnections(relinkToSocket, autoconnect, editorNodeInputSocketIndex, graph);
|
||
|
} else {
|
||
|
if (!this->isConnected() && autoconnect) {
|
||
|
Node* node = (Node*)this->getNode();
|
||
|
switch (this->getActualDataType()) {
|
||
|
case COM_DT_UNKNOWN:
|
||
|
case COM_DT_COLOR:
|
||
|
node->addSetColorOperation(graph, relinkToSocket, editorNodeInputSocketIndex);
|
||
|
break;
|
||
|
case COM_DT_VECTOR:
|
||
|
node->addSetVectorOperation(graph, relinkToSocket, editorNodeInputSocketIndex);
|
||
|
break;
|
||
|
case COM_DT_VALUE:
|
||
|
node->addSetValueOperation(graph, relinkToSocket, editorNodeInputSocketIndex);
|
||
|
break;
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
SocketConnection * newConnection = new SocketConnection();
|
||
|
OutputSocket * fromSocket = this->getConnection()->getFromSocket();
|
||
|
newConnection->setToSocket(relinkToSocket);
|
||
|
newConnection->setFromSocket(fromSocket);
|
||
|
relinkToSocket->setConnection(newConnection);
|
||
|
fromSocket->addConnection(newConnection);
|
||
|
graph->addSocketConnection(newConnection);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void InputSocket::relinkConnections(InputSocket *relinkToSocket, bool autoconnect, int editorNodeInputSocketIndex, ExecutionSystem* graph) {
|
||
|
if (!isConnected()) {
|
||
|
if (autoconnect) {
|
||
|
Node* node = (Node*)this->getNode();
|
||
|
switch (this->getActualDataType()) {
|
||
|
case COM_DT_UNKNOWN:
|
||
|
case COM_DT_COLOR:
|
||
|
node->addSetColorOperation(graph, relinkToSocket, editorNodeInputSocketIndex);
|
||
|
break;
|
||
|
case COM_DT_VECTOR:
|
||
|
node->addSetVectorOperation(graph, relinkToSocket, editorNodeInputSocketIndex);
|
||
|
break;
|
||
|
case COM_DT_VALUE:
|
||
|
node->addSetValueOperation(graph, relinkToSocket, editorNodeInputSocketIndex);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return;
|
||
|
}
|
||
|
SocketConnection *connection = this->getConnection();
|
||
|
connection->setToSocket(relinkToSocket);
|
||
|
relinkToSocket->setConnection(connection);
|
||
|
this->setConnection(NULL);
|
||
|
}
|
||
|
|
||
|
const ChannelInfo* InputSocket::getChannelInfo(const int channelnumber) {
|
||
|
if (this->isConnected() && this->connection->getFromSocket()) {
|
||
|
return this->connection->getFromSocket()->getChannelInfo(channelnumber);
|
||
|
} else {
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool InputSocket::isStatic() {
|
||
|
if (isConnected()) {
|
||
|
NodeBase* node = this->getConnection()->getFromNode();
|
||
|
if (node) {
|
||
|
return node->isStatic();
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
SocketReader* InputSocket::getReader() {
|
||
|
return this->getOperation();
|
||
|
}
|
||
|
|
||
|
NodeOperation* InputSocket::getOperation() const {
|
||
|
if (isConnected()) {
|
||
|
return (NodeOperation*)this->connection->getFromSocket()->getNode();
|
||
|
} else {
|
||
|
return NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
float* InputSocket::getStaticValues() {
|
||
|
/* XXX only works for socket types with actual float input values.
|
||
|
* currently all compositor socket types (value, rgba, vector) support this.
|
||
|
*/
|
||
|
bNodeSocket *b_socket = this->getbNodeSocket();
|
||
|
static float default_null = 0.0f;
|
||
|
|
||
|
switch (this->getDataType()) {
|
||
|
case COM_DT_VALUE:
|
||
|
return &((bNodeSocketValueFloat*)b_socket->default_value)->value;
|
||
|
case COM_DT_COLOR:
|
||
|
return ((bNodeSocketValueRGBA*)b_socket->default_value)->value;
|
||
|
case COM_DT_VECTOR:
|
||
|
return ((bNodeSocketValueVector*)b_socket->default_value)->value;
|
||
|
default:
|
||
|
/* XXX this should never happen, just added to please the compiler */
|
||
|
return &default_null;
|
||
|
}
|
||
|
}
|